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