【问题标题】:Why doesn't map[]interface{} take map[]SpecificInterface为什么 map[]interface{} 不采用 map[]SpecificInterface
【发布时间】:2019-05-18 17:57:07
【问题描述】:

Go 规范指出:

接口类型的变量可以存储任何类型的值,方法集是接口的任何超集。

这样我可以

type Source interface{}
type SourceImpl struct{}

var s Source
g := new(interface{})
s = new(SourceImpl)

*g = s

但是,我不能对地图做同样的事情:

generic := make(map[string]*interface{})
specific := make(map[string]*Source)

generic = specific

给予:

cannot use specific (type map[string]*Source) as type map[string]*interface {} in assignment

这是为什么呢?可以不使用类型断言将特定类型的映射传递/分配给泛型类型的映射吗?

【问题讨论】:

  • 问题中的设置与地图中的类型不匹配。设置显示*Source 可以分配给interface{}。为了匹配映射中的类型,设置应该显示*Source 可以分配给*interface{}。这是不允许的。无论如何,请参阅第一条评论中链接的常见问题条目。
  • 注意interface{}已经是一个指针类型
  • @ThunderCat 是的,感谢您的提示

标签: go interface casting


【解决方案1】:

因为map[]interface{}map[]SpecificInterface 是两种不同的类型。 如果将泛型类型设为空接口,它就可以工作。

var generic interface{}
specific := make(map[string]*Source)

generic = specific

但如果你这样做了,当你想使用你的地图时,你需要做一些类型切换或类型断言。

【讨论】:

    【解决方案2】:

    由于 Go 是一种静态类型语言,虽然 interface{} 和 Source 具有相同的底层类型,但它们不能在没有转换的情况下相互分配。
    因此,您必须在循环中进行转换:

    generic := make(map[string]interface{})
    specific := make(map[string]*Source)
    
    for k, v := range specific {
        generic[k] = v
    }
    

    您是否注意到我将 *interface{} 更改为 interface{} ? 这是您代码的另一个问题,在 Go 中指向 interface{} 的指针没有意义。

    【讨论】:

      【解决方案3】:

      虽然没有直接回答这个问题,但似乎 Go 社区正在慢慢改变主意并开始考虑支持 Go2 的泛型:https://go.googlesource.com/proposal/+/master/design/go2draft-generics-overview.md

      【讨论】:

        猜你喜欢
        • 2015-01-14
        • 2017-07-13
        • 2016-08-06
        • 1970-01-01
        • 2021-05-26
        • 2015-11-26
        • 2011-08-01
        • 1970-01-01
        相关资源
        最近更新 更多