151

I am trying to generate a map and then convert that to a yaml file like this:

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

I think I am missing something important while creating the map. My code is below.

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

It is giving the following error:

panic: runtime error: assignment to entry in nil map
Rick-777
  • 9,714
  • 5
  • 34
  • 50
Kasinath Kottukkal
  • 2,471
  • 4
  • 22
  • 28
  • 2
    possible duplicate of [Runtime error: "assignment to entry in nil map"](http://stackoverflow.com/questions/15117513/runtime-error-assignment-to-entry-in-nil-map) – Jonathan Hall Jul 03 '15 at 20:18

5 Answers5

192

You have not initialized your inner map. Before your for loop you can add m["uid"] = make(map[string]T) and then assign the name.

Makpoc
  • 3,921
  • 1
  • 19
  • 19
35

You should check if the map is nil and initialize one if it's nil inside the for loop:

if m["uid"] == nil {
    m["uid"] = map[string]T{}
}
sharno
  • 630
  • 8
  • 14
21

Probably the map you have define is by using variable var m map[string]interface{}

Instead use m := make(map[string]interface{}) to avoid respective error

Aman Agarwal
  • 396
  • 3
  • 5
10

There is thing as per the error

assignment to entry in nil map

For nested maps when assign to the deep level key we needs to be certain that its outer key has value. Else it will say that the map is nil. For eg in your case

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

m is a nested map which contains string key with map[string]T as value. And you are assign the value

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

here you can see the m["uid"] is nil and we are stating it contains a value [name] which is a key to nested value of type T. So first you need to assign value to "uid" or initialise it as

m["uid"] = make(map[string]T)
Himanshu
  • 12,071
  • 7
  • 46
  • 61
3

@Makpoc already answered the question. Here is some extra info from the Go Blog. (In the quote, m refers to an example from the blogpost. In this case, the problem is not m but m["uid"].)

Map types are reference types, like pointers or slices, and so the value of m above is nil; it doesn't point to an initialized map. A nil map behaves like an empty map when reading, but attempts to write to a nil map will cause a runtime panic; don't do that.

Telemachus
  • 19,459
  • 7
  • 57
  • 79
dj1986
  • 362
  • 2
  • 9
  • m is not nil, it is m["uid"] that is nil – Nic Jun 21 '21 at 21:41
  • @Nic (and for future Googlers): Yes and no. `m` in the quote refers to something from the quoted article. But yes, for this question, `m["uid"]` is the real problem rather than `m`. – Telemachus Aug 18 '23 at 10:46