2016-08-22 59 views
-1

我有一个名为Keys()拿到地图的所有键的功能,这里是代码:围棋,泛型,如何让地图的钥匙

func main() { 
    m2 := map[int]interface{}{ 
     2:"string", 
     3:"int", 
    } 
    fmt.Println(Keys(m2)) 
} 
func Keys(m map[interface{}]interface{}) (keys []interface{}) { 
    for k := range m { 
     keys = append(keys, k) 
    } 
    return keys 
} 

但我得到

cannot use m2 (type map[int]interface {}) as type map[interface {}]interface {} in argument to Keys 

Go支持泛型,我应该如何修复我的代码?

+0

map [interface {}] interface {}和map [int] interface {}是不同的类型,这就是为什么你会得到错误。也许你可以改变m2来键入map [interface {}] interface {} – zzn

回答

3

1- Golang是强类型语言,因此map[int]interface{}map[interface{}]interface{}不兼容。
int是不同的类型interface{}, 看到:Go: What's the meaning of interface{}?

2 - 不,Golang不支持泛型,这是非常好的,因为它使语言简单,快捷。


你有一些选择:

如果你不想改变使用的地图类型:
1您可以编辑功能:func Keys(m map[int]interface{}) []int,像这样的工作示例代码:

package main 

import "fmt" 

func main() { 
    m2 := map[int]interface{}{ 
     2: "string", 
     3: "int", 
    } 
    fmt.Println(Keys(m2)) 
} 

func Keys(m map[int]interface{}) []int { 
    keys := make([]int, len(m)) 
    i := 0 
    for k := range m { 
     keys[i] = k 
     i++ 
    } 
    return keys 
} 

输出(可以不是按顺序):

[2 3] 

2 - 或者你可以编辑功能:func Keys(m map[int]interface{}) []interface{},像这样的工作示例代码:

package main 

import "fmt" 

func main() { 
    m2 := map[int]interface{}{ 
     2: "string", 
     3: "int", 
    } 
    fmt.Println(Keys(m2)) 
} 

func Keys(m map[int]interface{}) []interface{} { 
    keys := make([]interface{}, len(m)) 
    i := 0 
    for k := range m { 
     keys[i] = k 
     i++ 
    } 
    return keys 
} 

输出(可以不按顺序):

[2 3] 

如果您不想更改Keys使用的功能:
3-您可以编辑地图到:map[interface{}]interface{},就像这个工作示例代码:

package main 

import "fmt" 

func main() { 
    m2 := map[interface{}]interface{}{ 
     2: "string", 
     3: "int", 
    } 
    fmt.Println(Keys(m2)) 
} 

func Keys(m map[interface{}]interface{}) []interface{} { 
    keys := make([]interface{}, len(m)) 
    i := 0 
    for k := range m { 
     keys[i] = k 
     i++ 
    } 
    return keys 
} 

4-您也可以使用reflect包一些使用情况,但随着性能(速度)的处罚。
并参见:The Laws of Reflection

0

除了Amd的解决方案,如果您不想更改使用的地图类型,还可以使用反射库。

func main() { 
    m2 := map[int]interface{}{ 
     2: "string", 
     3: "int", 
    } 

    k := Keys(m2) 

    fmt.Printf("Keys: %v\n", k) 
} 

func Keys(m interface{}) (keys []interface{}) { 
    v := reflect.ValueOf(m) 
    if v.Kind() != reflect.Map { 
     fmt.Errorf("input type not a map: %v", v) 
    } 

    for _, k := range v.MapKeys() { 
     keys = append(keys, k.Interface()) 
    } 
    return keys 

} 

请注意,如果您使用此解决方案,从Keys返回键将包含包裹在一个界面本身每个键值。因此,要获得实际值,您可能需要键入断言:

k := Keys(m2) 
k1 := k[0].(int) // k[0] is an interface value, k1 is an int 

Working Code