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

huangapple go评论72阅读模式
英文:

Using map[string]int as parameter of type map[interface{}]interface{}

问题

我有一个函数:

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{},它不应该工作吗?

我搜索了一下,找到的最好的答案是https://stackoverflow.com/questions/26975880/convert-mapinterface-interface-to-mapstringstring,但它没有解答为什么我不能将m作为参数使用。

我还相信,如果函数的参数只是interface{},它也会工作,因为map[something][something]实现了interface,对吗?什么是最好的方法来解决这个问题,为什么在我的情况下它不起作用?

英文:

I have a function:

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

In which I'm trying to call like this:

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

But I'm getting

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

Shouldn't it work since string and int both implement interface{}?

I've searched and the best I could find was https://stackoverflow.com/questions/26975880/convert-mapinterface-interface-to-mapstringstring but it won't answer why I cannot use m as an argument.

I also believe that if the argument of the function were only interface{} it would work too, since map[something][something] implements interface, right? What is the best way to do it, and why it won't work in my case?

答案1

得分: 12

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

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

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

请注意:如果您希望以后将值用作原始类型,您将需要使用类型断言,因为它们现在是'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:我不理解为什么问题会被投票否决,我认为这是一个合理的问题...

英文:

A solution to your problem, simply initiate the map as an empty interface of empty interfaces:

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

then you can assign any type key or value you want in the 'ReturnTuples' function.

playground example

NOTE: remember that if you want to use the values later as the original types, you will need to use type assertion because now they are of type interface{}

You may do something this like this, were anything is one map value which you can get using a for loop:

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")
}

If you are looking for an explanation for the "why"
@ymonad gave a full answer so I wont repeat it again.

hope it make sense

PS: don't get the down votes on the question, a legit one in my eyes...

答案2

得分: 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 {
        ....
    }
}
英文:

You can type assert in the function itself.

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

huangapple
  • 本文由 发表于 2017年2月23日 18:45:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/42413495.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定