Go - append to slice in struct

Hmm... This is the most common mistake that people make when appending to slices in Go. You must assign the result back to slice.

func (box *MyBox) AddItem(item MyBoxItem) []MyBoxItem {
    box.Items = append(box.Items, item)
    return box.Items
}

Also, you have defined AddItem for *MyBox type, so call this method as box.AddItem(item1)


package main

import (
        "fmt"
)

type MyBoxItem struct {
        Name string
}

type MyBox struct {
        Items []MyBoxItem
}

func (box *MyBox) AddItem(item MyBoxItem) []MyBoxItem {
        box.Items = append(box.Items, item)
        return box.Items
}

func main() {

        item1 := MyBoxItem{Name: "Test Item 1"}

        items := []MyBoxItem{}
        box := MyBox{items}

        box.AddItem(item1)

        fmt.Println(len(box.Items))
}

Playground


Output:

1

Though both answers are perfectly fine. There are two more changes that can be done,

  1. Getting rid of the return statement as the method is called for a pointer to the struct, so the slice is automatically modified.
  2. There is no need to initialise an empty slice and assign it to the struct
    package main    

    import (
        "fmt"
    )

    type MyBoxItem struct {
        Name string
    }

    type MyBox struct {
        Items []MyBoxItem
    }

    func (box *MyBox) AddItem(item MyBoxItem) {
        box.Items = append(box.Items, item)
    }


    func main() {

        item1 := MyBoxItem{Name: "Test Item 1"}
        item2 := MyBoxItem{Name: "Test Item 2"}

        box := MyBox{}

        box.AddItem(item1)
        box.AddItem(item2)

        // checking the output
        fmt.Println(len(box.Items))
        fmt.Println(box.Items)
    }

Tags:

Go