2017-03-20 10 views
2

struct定義の下に2つのメソッドを持つstructが1つあります。構造体の名前とメソッドの名前をparamとして使用する別の場所を呼び出したいと思います。文字列名でメソッドを呼び出すにはどうすればよいでしょうか?

次のように構造体のコードに次のように

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

メソッドの定義:

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

に続いては、私が電話をかけたいものです:

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

funcall(s,t)を満たすためにどのように?

+0

文字列指定された型のインスタンスを作成するためhttp://stackoverflow.com/questions/10210188/instance-new-type-golangを参照してください。 –

答えて

4

名前で指定された型のメソッドを呼び出すのは簡単です(reflectionを使用)。この例を参照してください:

type My struct{} 

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

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

出力(Go Playground上でそれを試してみてください):

MyFunc called 

あなたのコードが明示的に参照していない場合、その文字列の名前指定された型は、可能ではない「インスタンス化」実行可能なバイナリには含まれないこともあります。詳細については、Call all functions with special prefix or suffix in Golangを参照してください。およびSplitting client/server code

考えられる回避策は、(名前で値を作成する前に)使用する前に入力する、ある種の「タイプレジストリ」を使用することです。タイプレジストリ(マップでもよい)は、値またはファクトリ関数をタイプ名からマップすることができる。

上記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) 

そして、ファクトリ関数を格納するレジストリは、次のようになります(それを試してみてくださいGo Playground)上:

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

v := registry["My"]() 
meth := reflect.ValueOf(v).MethodByName("MyFunc") 
meth.Call(nil) 
関連する問題