将 map[string]int 作为 map[interface{}]interface{} 类型的参数使用

22

我有一个函数:

func ReturnTuples(map_ map[interface{}]interface{}) [][]interface{} {

我试图这样调用:

m := make(map[string]int)
m["k1"] = 7
m["k2"] = 13
fmt.Println(ReturnTuples(m))

但我正在获得

cannot use m (type map[string]int) as type map[interface {}]interface {} in argument to ReturnTuples

stringint都实现了interface{},那么为什么它不能工作呢?

我已经搜索过了,最好的结果是将map[interface{}]interface{}转换为map[string]string,但它并不能回答为什么我不能使用m作为参数。

我还相信,如果函数的参数只有interface{},也可以工作,因为map[something][something]实现了interface,对吗?哪种方法是最好的,为什么在我的情况下它不起作用呢?


3
https://golang.org/doc/faq#covariant_types - Volker
@Volker 但我没有看到方法类型错误,因为我甚至没有强制执行方法类型,因为我只是打印函数的返回值。正如编译器所说,问题在于参数类型。 - user6791424
5
你无法将 map[string]int 传递给 map[interface{}]interface{} 的原因是 stringintinterface{} 具有不同的数据结构。string 是一个单指针,可能是64位的,int 可能是有符号的64位值,而 interface{} 则是由两个名为 emptyInterface 的指针组成的结构。 - ymonad
2
你可以将 stringint 传递给 interface{} 的原因是,Golang的运行时会在需要时使用 runtime.convT2E() 进行隐式转换。 - ymonad
3
这意味着,如果你想将map[string]int转换为map[interface{}]interface{},你需要对所有的键和值调用runtime.convT2E函数进行转换。当然,你可以编写代码来实现这个操作,但是Golang的运行时库不会自动执行这个操作。 - ymonad
显示剩余2条评论
2个回答

12

解决问题的方法是,将地图初始化为空接口的空接口:

m := map[interface{}]interface{}

然后你可以在'ReturnTuples'函数中分配任何类型的键或值。

playground example

注意:如果您想以后使用原始类型的值,您需要使用类型断言,因为现在它们是类型interface{}

您可以像这样做某些事情,其中anything是一个地图值,您可以使用for循环获取:

switch v := anything.(type) {
      case string:
            fmt.Println(v)
      case int32, int64:
            fmt.Println(v)
      case string:
            fmt.Println(v)
      case SomeCustomType:
            fmt.Println(v)
      default:
            fmt.Println("unknown")
}
如果你正在寻找“为什么”的解释,@ymonad已经给出了完整的答案,所以我不会再重复了。
希望这有意义。
PS:我不理解为什么这个问题会被踩,我认为这是一个合法的问题...

1
谢谢,这正是我所需要的。是啊,我也厌倦了这些踩票。现在所有的东西都被踩票了... - user6791424
看起来游乐场链接由于“法律原因不可用”不再有效。 - Stephen L

1

在函数本身中,您可以输入assert。

func test(m interface{},key interface{}) bool { // Map is passed as reference
        ma := m.(map[interface{}]interface{})
        if _, ok := ma[key]; ok == false {
        ....
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接