如何在动态类型的变量上调用方法?

时间:2016-04-06 01:11:30

标签: go

我发现了两个问题并阅读了它们:

但我仍然不明白为什么我尝试映射出现错误的对象:

./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()
}

这总是适用于动态语言,所以我想念一些静态语言。

2 个答案:

答案 0 :(得分:3)

表达式

m := Mstruct["MyStruct"]

short variable declarationspecification

  

如果存在类型,则为每个变量赋予该类型。除此以外,   每个变量都给出相应初始化的类型   作业中的价值。

由于该表达式中不存在类型,因此变量m被赋予相应初始化值Mstruct["MyStruct"]的类型。该类型为interface{}

根据您当前的导入,interface{}的方法集为空。您无法在ype interface{}的值上调用任何内容。因此编译器拒绝

m.Action()

您似乎希望基于其动态类型m*MyStruct用作方法接收器。您可以使用type assertion执行此操作。例如

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

规范说明

  

如果类型断言成立,则表达式的值为值   存储在x中,其类型为T

此处的类型为*MyStruct,它是Action方法的接收器类型。因此,您可以使用变量dynamic调用该方法。

答案 1 :(得分: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()
}

使用类型断言。在断言它不是nil且具有指定类型之后,您可以将其视为该类型。

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

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