Ошибка выполнения: присвоение записи в карте nil

102

Я пытаюсь создать карту, а затем преобразовать ее в файл yaml следующим образом:

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

Я думаю, что при создании карты упускаю кое-что важное. Мой код ниже.

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

Это дает следующую ошибку:

panic: runtime error: assignment to entry in nil map
Касинатх Коттуккал
источник

Ответы:

138

Вы не инициализировали свою внутреннюю карту. Перед циклом for вы можете добавить, m["uid"] = make(map[string]T)а затем присвоить имя.

Макпок
источник
21

Вы должны проверить, является ли карта равной нулю, и инициализировать ее, если она равна нулю внутри цикла for:

if m["uid"] == nil {
    m["uid"] = map[string]T{}
}
шарно
источник
5

Есть вещь по ошибке

assignment to entry in nil map

Для вложенных карт при назначении ключу глубокого уровня мы должны быть уверены, что его внешний ключ имеет значение. В противном случае он скажет, что карта равна нулю. Например, в вашем случае

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

m - это вложенная карта, которая содержит stringключ со map[string]Tзначением as. И вы присваиваете значение

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

здесь вы можете увидеть m["uid"]это, nilи мы заявляем, что он содержит значение, [name]которое является ключом к вложенному значению типа T. Итак, сначала вам нужно присвоить значение "uid" или инициализировать его как

m["uid"] = make(map[string]T)
Химаншу
источник
1

@Makpoc уже ответил на вопрос. просто добавляю дополнительную информацию.

Типы карт - это ссылочные типы, такие как указатели или срезы, поэтому значение m выше равно нулю; он не указывает на инициализированную карту. При чтении карта nil ведет себя как пустая карта, но попытки записи в карту nil вызовут панику во время выполнения; не делай этого. больше информации о карте

dj1986
источник