2016-04-06 3 views
0

私は2つの質問を発見し、それらを読む:変数の動的型でメソッドを呼び出す方法はありますか?

をしかし、私はエラーを得たオブジェクトをマッピングしようとした理由は、私はまだ理解していない:

./aaa.go:21: m.Action undefined (type interface {} is interface with no methods)

type MyStruct struct { 
} 

func (a *MyStruct) Action() { 
    fmt.Println("Hello") 
} 

func main() { 
    var Mstruct map[string]interface{} 
    Mstruct = make(map[string]interface{}, 100) 
    Mstruct["MyStruct"] = &MyStruct{} 
    m := Mstruct["MyStruct"] 
    fmt.Println(reflect.TypeOf(m)) // *main.MyStruct 
    m.Action() 
} 

これは常に動的言語で動作するので、私は静的言語で何かを逃してしまいます。

答えて

3

発現

m := Mstruct["MyStruct"] 

short variable declarationあります。 specification状態

If a type is present, each variable is given that type. Otherwise, each variable is given the type of the corresponding initialization value in the assignment.

タイプは、その発現が存在しないため、変数mは、対応する初期値、Mstruct["MyStruct"]のタイプが与えられます。そのタイプはinterface{}です。

現在のインポートに基づいて、interface{}のメソッドセットは空です。 ype interface{}の値で呼び出すことはできません。そのため、コンパイラは、あなたがその動的な型、*MyStructに基づく方式の受信機としてmを使用するように見える

m.Action() 

を拒否します。あなたはtype assertionでそれを行うことができます。例えば

dynamic := m.(*MyStruct) 
dynamic.Action() 

仕様状態

If the type assertion holds, the value of the expression is the value stored in x and its type is T .

その種類は、ここにあなたのAction方法の受信機タイプである*MyStructです。したがって、変数dynamicを使用してメソッドを呼び出すことができます。

2
func main() { 
    var Mstruct map[string]interface{} 
    Mstruct = make(map[string]interface{}, 100) 
    Mstruct["MyStruct"] = &MyStruct{} 
    m := Mstruct["MyStruct"].(*MyStruct) //This is a type assertion 
    fmt.Println(reflect.TypeOf(m)) // *main.MyStruct 
    m.Action() 
} 

タイプアサーションを使用します。指定された型ではないことを宣言した後、その型として扱うことができます。

https://golang.org/ref/spec#Type_assertions

https://play.golang.org/p/bJib9g7kDY

関連する問題