Append content to slice into a nested struct does not work

Issue

I have two nested structs like this:

type Block struct {
    ID       string
    Contents []string
}

type Package struct {
    Name   string
    Blocks []Block
}

Original package (p) does not change when I try to append a new Content in a specific block.

for _, b := range p.Blocks {
    if b.ID == "B1" {
        fmt.Println("Adding a new content")
        b.Contents = append(b.Contents, "c3")
    }
}

Example:

https://play.golang.org/p/5hm6RjPFk8o

Solution

This is happening because this line:

for _, b := range p.Blocks {

creates a copy of each element in the slice, and in this case this means creating a copy of each Block in the slice. So when you then make the changes in the loop body, you are making them to the copy of the Block, instead of to the Block in the slice.

If you instead use the index to get a pointer to each Block, e.g.

for i := range p.Blocks {
    b := &p.Blocks[i]

it works as expected:

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

Alternatively, you can make the changes to the copy (as in your original code), and then copy the modified value back to the slice:

https://go.dev/play/p/kVHTk-OTyC3

Answered By – CAFxX

Answer Checked By – Willingham (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.