2017-02-23 54 views
6

У меня есть функция:Использование карты [строка] INT в качестве параметра типа карты [интерфейс {}] Интерфейс {}

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 

не должна ли она работать так string и int как реализовать interface{} ?

Я искал, и лучшее, что я мог найти, было Convert map[interface {}]interface {} to map[string]string, но оно не ответит, почему я не могу использовать m в качестве аргумента.

Я также считаю, что если аргумент функции был только interface{}, это тоже сработало бы, так как map[something][something] реализует interface, правильно? Каков наилучший способ сделать это, и почему это не будет работать в моем случае?

+2

https://golang.org/doc/faq#covariant_types – Volker

+0

@ Volker, но я не вижу неправильного типа метода, я даже не применял тип метода, так как я просто печатаю возвращаемое значение функции. Проблема, как говорит компилятор, относится к типу аргумента –

+3

Причина, по которой вы не можете передать 'map [string] int', поскольку это' map [interface {}] interaface {} '- это' string', 'int', и 'interface {}' все имеют разную структуру данных. 'string' - это единственный указатель, который может быть 64 бит,' int', возможно, подписан 64-битным значением, однако 'interface {}' является структурой двух указателей с именем [emptyInterface] (https://golang.org/src/reflect/value .go # L174) – ymonad

ответ

6

Решение вашей проблемы, просто начать карту как пустой интерфейс пустых интерфейсов:

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

, то вы можете назначить любую клавишу типа или значение, которое вы хотите в функции 'ReturnTuples.

playground example

Примечание: помните, что если вы хотите использовать значение позже в качестве исходных типов, вам нужно будет использовать тип утверждение, потому что теперь они типа interface{}

Вы можете сделать что-то это, как это были anything одно значение карты, которые вы можете получить, используя для цикла:

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

Спасибо, это именно то, что мне нужно. И да, я устал от этих downvotes. Теперь все приостановлено ... –

+0

Похоже, что ссылка на игровые площадки больше не работает из-за «Недоступной для юридических причин». –

+0

Stephen L только что проверил, и это сработало –

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