Iterowanie po mapie golang

89

Mam mapę typu: map[string]interface{}

I na koniec mogę stworzyć coś takiego (po deserializacji z pliku yml za pomocą goyaml)

mymap = map[foo:map[first: 1] boo: map[second: 2]]

Jak mogę iterować tę mapę? Próbowałem następujących rzeczy:

for k, v := range mymap{
...
}

Ale pojawia się błąd:

cannot range over mymap
typechecking loop involving for loop

Proszę pomóż.

ashokgelal
źródło
Czy można dostarczyć przypadek testowy? Trudno jest zdiagnozować problem na podstawie tego, co opublikowałeś, ponieważ nie ma nic nieodłącznego od tego, co opublikowałeś, co mogłoby spowodować pętlę sprawdzania typu. W szczególności mam problem ze znalezieniem pętli sprawdzającej typ w treści funkcji.
SteveMcQwark

Odpowiedzi:

107

Na przykład,

package main

import "fmt"

func main() {
    type Map1 map[string]interface{}
    type Map2 map[string]int
    m := Map1{"foo": Map2{"first": 1}, "boo": Map2{"second": 2}}
    //m = map[foo:map[first: 1] boo: map[second: 2]]
    fmt.Println("m:", m)
    for k, v := range m {
        fmt.Println("k:", k, "v:", v)
    }
}

Wynik:

m: map[boo:map[second:2] foo:map[first:1]]
k: boo v: map[second:2]
k: foo v: map[first:1]
peterSO
źródło
4

Możesz zrobić to jednym wierszem:

mymap := map[string]interface{}{"foo": map[string]interface{}{"first": 1}, "boo": map[string]interface{}{"second": 2}}
for k, v := range mymap {
    fmt.Println("k:", k, "v:", v)
}

Wynik to:

k: foo v: map[first:1]
k: boo v: map[second:2]
Bryce
źródło
20
Idź przysłowie: nie bądź mądry, bądź wyraźny. One-lineers nie są celem w Go.
Inanc Gumus
2

Możesz po prostu napisać to w multilinii w ten sposób,

$ cat dict.go
package main

import "fmt"

func main() {
        items := map[string]interface{}{
                "foo": map[string]int{
                        "strength": 10,
                        "age": 2000,
                },
                "bar": map[string]int{
                        "strength": 20,
                        "age": 1000,
                },
        }
        for key, value := range items {
                fmt.Println("[", key, "] has items:")
                for k,v := range value.(map[string]int) {
                        fmt.Println("\t-->", k, ":", v)
                }

        }
}

A wynik:

$ go run dict.go
[ foo ] has items:
        --> strength : 10
        --> age : 2000
[ bar ] has items:
        --> strength : 20
        --> age : 1000
han solo
źródło