Błąd wykonania: przypisanie do wpisu w mapie zerowej

101

Próbuję wygenerować mapę, a następnie przekonwertować ją na plik yaml w następujący sposób:

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

Myślę, że podczas tworzenia mapy brakuje mi czegoś ważnego. Mój kod jest poniżej.

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)
}

Daje następujący błąd:

panic: runtime error: assignment to entry in nil map
Kasinath Kottukkal
źródło

Odpowiedzi:

136

Nie zainicjowałeś swojej mapy wewnętrznej. Przed pętlą for możesz dodać, m["uid"] = make(map[string]T)a następnie przypisać nazwę.

Makpoc
źródło
20

Powinieneś sprawdzić, czy mapa jest zerowa i zainicjować jedną, jeśli jest zerowa w pętli for:

if m["uid"] == nil {
    m["uid"] = map[string]T{}
}
sharno
źródło
5

Jest coś jak na błąd

assignment to entry in nil map

W przypadku map zagnieżdżonych, gdy przypisujemy je do klucza głębokiego poziomu, musimy mieć pewność, że jego klucz zewnętrzny ma wartość. W przeciwnym razie powie, że mapa jest zerowa. Na przykład w Twoim przypadku

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

m to zagnieżdżona mapa, która zawiera stringklucz z map[string]Twartością. I przypisujesz wartość

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

tutaj widać m["uid"]is nili stwierdzamy, że zawiera wartość, [name]która jest kluczem do zagnieżdżonej wartości typu T. Więc najpierw musisz przypisać wartość do „uid” lub zainicjalizować ją jako

m["uid"] = make(map[string]T)
Himanshu
źródło
1

@Makpoc już odpowiedział na pytanie. po prostu dodając dodatkowe informacje.

Typy map są typami referencyjnymi, takimi jak wskaźniki lub wycinki, więc wartość m powyżej wynosi zero; nie wskazuje na zainicjowaną mapę. Mapa zerowa zachowuje się jak pusta mapa podczas czytania, ale próby zapisu do mapy zerowej spowodują panikę w czasie wykonywania; nie rób tego. więcej informacji o Mapie

dj1986
źródło