【问题标题】:Automatic Type Assertion In GoGo 中的自动类型断言
【发布时间】:2014-09-22 15:24:15
【问题描述】:

获取此代码示例 (playground):

package main

import (
  "fmt"
)

type Foo struct {
  Name string
}

var data = make(map[string]interface{})

func main() {
  data["foo"] = &Foo{"John"}

  foo := data["foo"].(*Foo)

  fmt.Println(foo.Name)
}

当我向data 添加一些内容时,类型会变成interface{},因此当我稍后检索该值时,我必须将原始类型声明回它。例如,有没有办法为data 定义一个getter 函数,它会自动断言类型?

【问题讨论】:

  • 为什么不给 data 一个自己的类型并在该类型上定义一个 Get(key string) *Foo 方法?

标签: struct interface go


【解决方案1】:

不是真的,除非你转向 reflect 并尝试以这种方式获取接口的类型。

但惯用(更快)的方式仍然是type assertion(必须在运行时检查的“类型转换”,因为data 只包含interface{} 值)。

如果数据要引用特定接口(而不是通用的interface{} 接口),例如我的mentioned here,那么您可以使用直接在其上定义的Name() 方法。

【讨论】:

    【解决方案2】:

    你可以做这样的事情,但你可能要考虑你的设计。你很少需要做这样的事情。

    http://play.golang.org/p/qPSxRoozaM

    package main
    
    import (
        "fmt"
    )
    
    type GenericMap map[string]interface{}
    
    func (gm GenericMap) GetString(key string) string {
        return gm[key].(string)
    }
    
    func (gm GenericMap) GetFoo(key string) *Foo {
        return gm[key].(*Foo)
    }
    
    func (gm GenericMap) GetInt(key string) int {
        return gm[key].(int)
    }
    
    var data = make(GenericMap)
    
    type Foo struct {
        Name string
    }
    
    func main() {
        data["foo"] = &Foo{"John"}
    
        foo := data.GetFoo("foo")
    
        fmt.Println(foo.Name)
    }
    

    您可能需要添加错误检查,以防密钥不存在或不是预期的类型。

    【讨论】:

    • 不知道你为什么被否决,我不会这样做,但它仍然是正确的。
    • 我做到了,因为我说的是 1 个 getter 来动态声明值,而不是一堆 getter。
    • 好吧,那是不可能的。除非您进行全面反思,否则使用其他语言会更好。
    • 那个 getter 应该返回什么类型?您必须指定一种,并且只有一种返回类型。
    猜你喜欢
    • 2014-01-12
    • 2016-12-13
    • 1970-01-01
    • 2021-02-10
    • 1970-01-01
    • 1970-01-01
    • 2015-08-15
    • 2011-10-26
    • 2014-01-22
    相关资源
    最近更新 更多