2016-08-22 61 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