use*_*534 3 methods struct dynamic go
我在结构定义下有一个带有 2 个方法的结构,我想在其他使用结构名称和方法名称作为参数的地方调用。
结构代码如下:
type ArticleForm struct {
Name string `required:"true" pattern:"^[A-Za-z0-9\u4e00-\u9fa5]{1,1024}$" valid:"Required;MaxSize(1024)"`
Category []Category `class:"multis" required:"true" valid:"Required" optionqs:"GetCategoryOption"`
Content string `class:"wysiwg_area" required:"true" valid:"Required"`
Tags []Tags `class:"multis_create" optionqs:"GetTagOptions"`
}
Run Code Online (Sandbox Code Playgroud)
方法定义如下:
func (this *ArticleForm) GetTagOptions() []Tags {
return GetTagsOptions(nil)
}
Run Code Online (Sandbox Code Playgroud)
以下是我想调用的内容:
func main() {
s := "models.ArticleForm"
t := "GetTagOptions"
//following is the question, how can i exec following?
funcall(s,t)
}
Run Code Online (Sandbox Code Playgroud)
如何履行funcall(s,t)?
icz*_*cza 11
调用由其名称给出的某种类型的方法很容易(使用反射)。看这个例子:
type My struct{}
func (m My) MyFunc() {
fmt.Println("MyFunc called")
}
func main() {
m := My{}
meth := reflect.ValueOf(m).MethodByName("MyFunc")
meth.Call(nil)
}
Run Code Online (Sandbox Code Playgroud)
输出(在Go Playground上试试):
MyFunc called
Run Code Online (Sandbox Code Playgroud)
“实例化”给定字符串名称的类型是不可能的,因为如果您的代码没有明确引用该类型,它甚至可能不会包含在可执行二进制文件中。具体参见调用Golang中所有带有特殊前缀或后缀的函数;和拆分客户端/服务器代码。
一种可能的解决方法是使用某种“类型注册表”,在使用它之前(在您想通过其名称创建值之前)填充它。类型注册表(可能是映射)可能包含reflect.Type从类型名称映射的值或工厂函数。
按照上面的My类型声明,存储reflect.Type值的类型注册表可能如下所示(在Go Playground上试试):
registry := map[string]reflect.Type{
"My": reflect.TypeOf((*My)(nil)).Elem(),
}
v := reflect.New(registry["My"]).Elem()
v.MethodByName("MyFunc").Call(nil)
Run Code Online (Sandbox Code Playgroud)
存储工厂函数的注册表可能如下所示(在Go Playground上试试):
registry := map[string]func() interface{}{
"My": func() interface{} { return My{} },
}
v := registry["My"]()
meth := reflect.ValueOf(v).MethodByName("MyFunc")
meth.Call(nil)
Run Code Online (Sandbox Code Playgroud)