59

I am trying to implement 2 simple structs as follows:

package main

import (
    "fmt"
)

type MyBoxItem struct {
    Name string
}

type MyBox struct {
    Items []MyBoxItem
}

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

func main() {

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

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

    AddItem(box, item1)  // This is where i am stuck

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

What am i doing wrong? I simply want to call the addItem method on the box struct and pass an item in

Marty Wallace
  • 34,046
  • 53
  • 137
  • 200

3 Answers3

109

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)

ShuklaSannidhya
  • 8,572
  • 9
  • 32
  • 45
21
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
zzzz
  • 87,403
  • 16
  • 175
  • 139
  • Why do you even need this line? - ` items := []MyBoxItem{}`. See this code - https://play.golang.org/p/7oq5qUuzypU. – Rahul Satal Jan 07 '20 at 10:06
18

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)
    }
arjunkhera
  • 929
  • 6
  • 23