初始化嵌套的结构图

The problem:

I've got a map of structs in another struct and I'd like to initialize the nested map of structs, but apparently that is not possible.

Code:

type Exporter struct {
    TopicsByName      map[string]Topic
}

type Topic struct {
    Name       string
    Partitions map[int32]Partition
}

type Partition struct {
    PartitionID   int32
    HighWaterMark int64
}

// Eventually I want to do something like:
e := Exporter{ TopicsByName: make(map[string]Topic) }
for _, topicName := range topicNames {
  // This does not work because "cannot assign to struct field e.TopicsByName[topicName].Partitions in map"
  e.TopicsByName[topicName].Partitions = make(map[int32]Partition)
}

// I wanted to initialize all these maps so that I can do
e.TopicsByName[x.TopicName].Partitions[x.PartitionID] = Partition{...}

I don't understand why I can not initialize the nested struct map above. Is it so bad to nest maps with struct as values? How can I fix this?

It is not possible to assign to a field in a map value. The fix is to assign a struct value to the map value:

for _, topicName := range []string{"a"} {
    e.TopicsByName[topicName] = Topic{Partitions: make(map[int32]Partition)}
}

You can initialize it like you'd expect:

e := Exporter{
    TopicsByName: map[string]Topic{
        "my-topic": Topic{
            Name: "my-topic",
            Partitions: map[int32]Partition{
                int32(1): Partition{
                    PartitionID:   int32(1),
                    HighWaterMark: int64(199),
                },
            },
        },
    },
}

This isn't directly answering the question, since you wanted to iterate over a list of topics, but if this is used in kafka testing, I highly recommend the more verbose/literal format above.

https://play.golang.org/p/zm3A7CIvbyu

If you've known an initialed value. Why don't do it like

   val := `
     {
         "topics_by_name": {
             "name1": {
                 "name":"topicname1",
                 "partions": {
                     1: {
                         "partion_id":1,
                         "high_water_mark":12,
                     },
                     2: {} 
                 }
              },
             "name2": {}
         }
     }
    `
func main() {
   var m map[string]interface{}
   // if m has be well designed, use your designed map is better
   // init
   json.Unmarshal(val, &m)
}