Go语言使用unsafe动态Call函数
Little_YangYang

reflect效率掉的太猛,这个是使用unsafe、interface与函数类型断言结合的方法来实现的,但是感觉不够优雅,看看后续想一想还有什么办法。

详细代码见下方,测试方法为test函数中的内容。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package main

import "unsafe"

type Type1 func(int)

type Type2 func()

type IC interface {
ret() unsafe.Pointer
name() string
}

type TestA struct {
}

func (a *TestA) name() string {
return "TestA"
}

func (a *TestA) test(i int) {
println("TestA", i)
}

func (a *TestA) ret() unsafe.Pointer {
reFn := a.test
ptr := unsafe.Pointer(&reFn)
return ptr
}

type TestB struct {
}

func (b *TestB) name() string {
return "TestB"
}

func (b *TestB) test() {
println("TestB")
}

func (b *TestB) ret() unsafe.Pointer {
reFn := b.test
ptr := unsafe.Pointer(&reFn)
return ptr
}

func call(fn IC) {
switch fn.name() {
case "TestA":
fnPtr := *(*Type1)(fn.ret())
fnPtr(1)

case "TestB":
fnPtr := *(*Type2)(fn.ret())
fnPtr()
}
}

//go:noinline
func test() {

a := &TestA{}
b := &TestB{}

call(a)
call(b)

}

func main() {
test()
}

输出内容:

1
2
TestA 1
TestB