转到-在结构中附加到切片

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

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