【问题标题】:How do you invoke a method on the dynamic type of a variable?如何在变量的动态类型上调用方法?
【发布时间】:2016-07-26 04:24:06
【问题描述】:

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

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

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

这总是适用于动态语言,所以我错过了静态语言的一些东西。

【问题讨论】:

    标签: go


    【解决方案1】:

    表达式

    m := Mstruct["MyStruct"]
    

    是short variable declaration。 specification 状态

    如果存在类型,则为每个变量指定该类型。否则, 每个变量都被赋予了相应的初始化类型 赋值中的值。

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

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

    m.Action()
    

    您似乎想使用m 作为基于其动态类型*MyStruct 的方法接收器。您可以使用type assertion 来做到这一点。例如

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

    规范说明

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

    这里的类型是*MyStruct,这是你的Action方法的接收者类型。因此,您可以使用变量 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()
      }
      

      使用类型断言。在你断言它不是 nil 并且是指定类型之后,你可以把它当作那个类型。

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

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

      【讨论】:

        猜你喜欢
        • 2018-05-20
        • 2010-10-13
        • 2011-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多