web-dev-qa-db-fra.com

Cartes imbriquées à Golang

func main() {
    var data = map[string]string{}
    data["a"] = "x"
    data["b"] = "x"
    data["c"] = "x"
    fmt.Println(data)
}

Ça court.

func main() {
    var data = map[string][]string{}
    data["a"] = append(data["a"], "x")
    data["b"] = append(data["b"], "x")
    data["c"] = append(data["c"], "x")
    fmt.Println(data)
}

Il court aussi.

func main() {
    var w = map[string]string{}
    var data = map[string]map[string]string{}
    w["w"] = "x"
    data["a"] = w
    data["b"] = w
    data["c"] = w
    fmt.Println(data)
}

Ça recommence!

func main() {
    var data = map[string]map[string]string{}
    data["a"]["w"] = "x"
    data["b"]["w"] = "x"
    data["c"]["w"] = "x"
    fmt.Println(data)
}

Mais ça échoue!?

Existe-t-il un problème avec les cartes imbriquées dans Go? Ou n'y a-t-il pas de support multi-supports pour les cartes imbriquées?

17
Özgür Yalçın

La valeur zéro pour les types de carte est nil. Ce n'est pas encore initialisé. Vous ne pouvez pas stocker de valeurs dans une carte nil, c'est une panique d'exécution.

Dans votre dernier exemple, vous initialisez la mappe (externe) data, mais elle ne contient aucune entrée. Lorsque vous l'indexez comme data["a"], puisqu'il n'y a pas encore d'entrée avec la clé "a", l'indexation renvoie la valeur zéro du type valeur qui est nil pour les mappes. Tenter d'assigner à data["a"]["w"] est donc une panique à l'exécution.

Vous devez d'abord initialiser une carte avant d'y stocker des éléments, par exemple:

var data = map[string]map[string]string{}

data["a"] = map[string]string{}
data["b"] = make(map[string]string)
data["c"] = make(map[string]string)

data["a"]["w"] = "x"
data["b"]["w"] = "x"
data["c"]["w"] = "x"
fmt.Println(data)

Sortie (essayez-le sur le Go Playground ):

map[a:map[w:x] b:map[w:x] c:map[w:x]]

Notez que lorsque vous déclarez une variable de type map et l'initialisez avec un littéral composite (comme dans var data = map[string]string{}), cela compte également comme initialisation.

Notez que vous pouvez également initialiser vos cartes imbriquées avec un littéral composite:

var data = map[string]map[string]string{
    "a": map[string]string{},
    "b": map[string]string{},
    "c": map[string]string{},
}

data["a"]["w"] = "x"
data["b"]["w"] = "x"
data["c"]["w"] = "x"
fmt.Println(data)

La sortie est la même. Essayez-le sur le Go Playground .

23
icza

En plus de la réponse de icza. L'initialisation de la carte peut être écrite sous la forme forme abrégée :

var data = map[string]map[string]string{
    "a": map[string]string{
        "w": "x"},
    "b": map[string]string{
        "w": "x"},
    "c": map[string]string{
        "w": "x"},
    "d": map[string]string{},
}
fmt.Println(data)

La sortie est la même. Essayez-le sur le Go Playground . La clé "d" a été ajoutée pour illustrer la correspondance avec une carte vide.

0
Vladimir Filin