简体   繁体   English

如何通过其字符串名称和字符串结构名称调用方法?

[英]How to call method by its string name with string struct name?

I have one struct with 2 methods under struct definition, I want to call in other place that use struct's name and method's name as param. 我在结构定义下有一个带有2个方法的结构,我想在其他地方调用以结构名和方法名作为参数的参数。

Struct code as following: 结构代码如下:

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"`
}

Method definition as following: 方法定义如下:

func (this *ArticleForm) GetTagOptions() []Tags {
return GetTagsOptions(nil)
}

Following is what I want to call: 以下是我要称呼的内容:

func main() {
s := "models.ArticleForm"
t := "GetTagOptions"
//following is the question, how can i exec following?
funcall(s,t)
}

How to fulfill the funcall(s,t) ? 如何实现funcall(s,t)

Calling a method of some type given by its name is easy (using reflection ). 调用由其名称给出的某种类型的方法很容易(使用反射 )。 See this example: 请参阅以下示例:

type My struct{}

func (m My) MyFunc() {
    fmt.Println("MyFunc called")
}

func main() {
    m := My{}
    meth := reflect.ValueOf(m).MethodByName("MyFunc")
    meth.Call(nil)
}

Output (try it on the Go Playground ): 输出(在Go Playground上尝试):

MyFunc called

"Instantiating" a type given its string name is not possible, because if your code does not explicitly refer to the type, it may not even be included in the executable binary. 给定其字符串名称来“实例化”一个类型是不可能的,因为如果您的代码未明确引用该类型,则它甚至可能不包含在可执行二进制文件中。 For details, see Call all functions with special prefix or suffix in Golang ; 有关详细信息,请参阅在Golang中使用特殊前缀或后缀调用所有函数 and Splitting client/server code . 以及分割客户端/服务器代码

A possible workaround is to use some kind of "type-registry" which you populate prior to using it (before you want to create a value by its name). 一种可能的解决方法是使用某种在您使用前填充的“类型注册表”(在您要通过名称创建值之前)。 The type registry (which may be a map) may hold reflect.Type values or factory functions mapped from the type name. 类型注册表(可能是映射)可以保存reflect.Type值或从类型名称映射的工厂函数。

Following the above My type declaration, a type registry storing reflect.Type values may look like this (try it on the Go Playground ): 在上面的My type声明之后,存储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)

And a registry that stores factory functions could look like this (try it on the Go Playground ): 存储工厂功能的注册表可能看起来像这样(在Go Playground上尝试):

registry := map[string]func() interface{}{
    "My": func() interface{} { return My{} },
}

v := registry["My"]()
meth := reflect.ValueOf(v).MethodByName("MyFunc")
meth.Call(nil)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM