当需要利用函数名变量调用函数的时候 一般都是为了封装,最近工作中遇到这么样的一个问题,百度出来的一些demo都很扯,估计一个人随便写了一个就被传开了吧,反正写的很麻烦,我研究了一下找出来这个比较好的方法,所以拿出来跟大家分享一下,反射还是很值得好好学习一下的,时间关系没细看,有时间要仔细看一下。
下面代码的目的:通过 字符串变量 "Signup",实现对 User.Signup 的调用
```
package main
import (
"fmt"
"reflect"
)
type User struct {
Name string
}
func (u User) Signup(name string, age int) {
fmt.Println("name123123:", name, "age:", age)
}
func (u User) Signin() {
fmt.Println("name:", u.Name)
}
func main() {
user := User{
Name: "zhangsan",
}
funcName := "Signup"
v := make([]reflect.Value, 3)
v[0] = reflect.ValueOf(user) // 数组第一个值必须为 结构体实例的reflect.Value, 如果函数没有参数,这个值也必须有,v[1],v[2]不需要
v[1] = reflect.ValueOf("likun")
v[2] = reflect.ValueOf(27)
m, _ := reflect.TypeOf(user).MethodByName(funcName) // m 类型为 reflect.Value
m.Func.Call(v) // 函数调用
}
```
总结:
1.m.Func 这是 Signup 函数的 reflect.Value,光有这个函数不够,还需要有结构体的实例 reflect.Value,这块我也没有特别懂,源码太复杂 我看不懂,我感觉有了 Signup 函数的 reflect.Value 应该不需要知道实例了吧,可能是源码对代码的组织问题引起的,模块之间耦合 没有互相共享信息。还请知道的大大们给讲下。
2. 要注意函数的接受者,golang 中对 函数的接收者很讲究的。
我想明白为什么一定要有 v[0] 了,它是为了 区分这个函数 的reciver的,因为同一个 结构体的方法,reciver 有两种,一种指针类型,一种非指针类型
#5
更多评论