golang 的 func 的反射使用,目前还没有很合适的优化手段
但是可以很巧妙地绕过对 func 的反射
我个人语文水平难以表达出来,所以举一个实例进行说明
gobench 测试大约 300 ns/op
type banana struct {
value int
value2 int
}
func apple(b *banana)int{
return b.value
}
func parse_func(fn interface{}) func() int{
fnt := reflect.TypeOf(fn)
fnv := reflect.ValueOf(fn)
param := fnt.In(0).Elem()
return func() int {
arg := reflect.New(param)
resp := fnv.Call([]reflect.Value{arg}) // 严重耗时
return resp[0].Interface().(int)
}
}
fn := parse_func(apple)
gobench 测试大约 50 ns/op
type banana struct {
value int
value2 int
}
type iBanana interface {
apple() int
}
func (b *banana) apple() int {
return b.value
}
func parse_func(b iBanana) func() int{
t := reflect.TypeOf(b)
param := t.Elem()
return func() int {
arg := reflect.New(param).Interface().(iBanana)
return arg.apple() // 无需反射
}
}
fn := parse_func(&banana{})
1
wfhtqp 2020-12-22 14:16:46 +08:00 1
都实现接口了还需要反射?
|
3
ArJun 2020-12-22 14:26:28 +08:00 1
楼主好像搞反了反射的实际意义··
|
4
wfhtqp 2020-12-22 14:28:26 +08:00 1
如果不是特殊的项目请保持简单,避免过度设计。
|
7
Mitt 2020-12-22 22:56:21 +08:00 via iPhone 1
你这传入了一个 interface 然后一套骚操作又把它转回那个 interface 了,那为啥不直接调用.apple() 反射的意义是啥
|
8
eudore 2020-12-23 08:44:31 +08:00 1
`arg := reflect.New(param).Interface().(iBanana)`迷之操作。 `return param.apple()` 不行?
|
10
Mitt 2020-12-23 12:34:21 +08:00 via iPhone 1
@fumeboy 那你应该是理解错了,如果你参数列表是动态的,那么你就不符合定义的接口了,也就无法传入了,你不能指定实体接口 而是用 interface{} 来反射
|
12
reus 2020-12-26 16:51:49 +08:00 via Android
你猜 (&banana{}).apple 是什么类型?
你这个 parse_func 纯粹多余。 |