Erreur d'exécution: affectation à l'entrée dans la carte nil

101

J'essaie de générer une carte, puis de la convertir en un fichier yaml comme celui-ci:

uid :
      kasi:
        cn: Chaithra
        street: fkmp
      nandan:
        cn: Chaithra
        street: fkmp
      remya:
        cn: Chaithra
        street: fkmp

Je pense qu'il me manque quelque chose d'important lors de la création de la carte. Mon code est ci-dessous.

package main

import (
    "fmt"
    "gopkg.in/yaml.v2"
)

type T struct {
    cn     string
    street string
}

func main() {
    names := []string{"kasi", "remya", "nandan"}

    m := make(map[string]map[string]T, len(names))
    for _, name := range names {

        //t := T{cn: "Chaithra", street: "fkmp"}

        m["uid"][name] = T{cn: "Chaithra", street: "fkmp"}

    }
    fmt.Println(m)

    y, _ := yaml.Marshal(&m)

    fmt.Println(string(y))
    //fmt.Println(m, names)
}

Il donne l'erreur suivante:

panic: runtime error: assignment to entry in nil map
Kasinath Kottukkal
la source

Réponses:

136

Vous n'avez pas initialisé votre carte interne. Avant votre boucle for, vous pouvez ajouter m["uid"] = make(map[string]T)puis attribuer le nom.

Makpoc
la source
20

Vous devriez vérifier si la carte est nulle et en initialiser une si elle est nulle dans la boucle for:

if m["uid"] == nil {
    m["uid"] = map[string]T{}
}
sharno
la source
5

Il y a une chose selon l'erreur

assignment to entry in nil map

Pour les cartes imbriquées lorsqu'elles sont affectées à la clé de niveau profond, nous devons être certains que sa clé externe a une valeur. Sinon, il dira que la carte est nulle. Par exemple dans votre cas

m := make(map[string]map[string]T, len(names))

m est une carte imbriquée qui contient la stringclé avec map[string]Tcomme valeur. Et vous attribuez la valeur

m["uid"][name] = T{cn: "Chaithra", street: "fkmp"}

ici vous pouvez voir le m["uid"]is nilet nous déclarons qu'il contient une valeur [name]qui est une clé de la valeur imbriquée de type T. Vous devez donc d'abord attribuer une valeur à "uid" ou l'initialiser comme

m["uid"] = make(map[string]T)
Himanshu
la source
1

@Makpoc a déjà répondu à la question. juste en ajoutant quelques informations supplémentaires.

Les types de carte sont des types de référence, comme des pointeurs ou des tranches, et donc la valeur de m ci-dessus est nulle; il ne pointe pas vers une carte initialisée. Une map nil se comporte comme une map vide lors de la lecture, mais les tentatives d'écriture sur une map nil provoqueront une panique à l'exécution; ne fais pas ça. plus d'infos sur la carte

dj1986
la source