2016-08-22 2 views
-1

У меня есть функция с именем Keys(), чтобы получить все ключи карты, вот код:Go, дженерики, как получить ключи карты

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 

Does Go поддерживает дженерики и как мне исправить свой код?

+0

map [interface {}] interface {} и map [int] interface {} - это другой тип, поэтому вы получаете ошибку. возможно, вы можете изменить m2, чтобы набрать карту интерфейса [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 пакет для некоторых случаев использования, но с производительностью (скорость) штрафа.
And See: 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.

Смежные вопросы