0

I'm trying to append to a slice within a map:

type MyOuterStruct struct{
    name string
    inners map[string]MyInnerStruct
}

type MyInnerStruct struct{
    name string
    list []int
}

func main() {
    
    ms := MyOuterStruct{
        name: "outer",
        inners: map[string]MyInnerStruct{
            "a": {name: "inner"},
        },
    }
    
    ms.inners["a"].list = append(ms.inners["a"].list, 4, 5, 6)
    
    fmt.Println(ms.inners["a"].list)

    //cannot assign to struct field ms.inners["a"].list in map
}

I know the issue is I'm assigning to an "unaddressable" field, but I'm not sure how to structure this properly.

I've tried the following

myCurrentList := ms.inners["a"].list
myCurrentList = append(myCurrentList, 4, 5, 6)
ms.inners["a"].list = myCurrentList

But this wasn't correct either.

How should I structure the MyInnerStruct so that I can have access to a dynamic slice list than I can append to?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
ZAR
  • 2,550
  • 4
  • 36
  • 66
  • Why the downvote? I can edit the question if it requires refinement. Appending to arrays and slices within maps and structs seems to be a common issue on StackOverflow. – ZAR May 05 '21 at 15:01
  • 1
    Votes are also a reflection on usefulness to the community, so even a valid question may not be deemed useful. There are thousands of examples of users misunderstanding the language fundamentals, so questions like this are unlikely to be upvoted. – JimB May 05 '21 at 21:07

1 Answers1

3

The problem is that ms.inners["a"] returns a copy of the value stored for that key. So when you modify a member of that copy, it is not reflected on the copy stored in the map.

The easiest solution is to define the map as:

map[string]*MyInnerStruct

This way, ms.inners["a"] returns a pointer to the value stored in the map. Another solution is:

x:=ms.inners["a"]
x.list = myCurrentList
ms.inners["a"]=x

This copies the struct stored in the map to x, modifies it, and copies it back.

Burak Serdar
  • 46,455
  • 3
  • 40
  • 59
  • Yes! Thank you for your help and clear explanation. This now makes sense to me. Will accept answer once SO allows. – ZAR May 05 '21 at 15:04