Go – 在结构体中向切片追加元素

huangapple go评论82阅读模式
英文:

Go - append to slice in struct

问题

我正在尝试实现以下两个简单的结构体:

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)  // 这是我卡住的地方

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

我做错了什么?我只是想在box结构体上调用addItem方法并传入一个item。

英文:

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

答案1

得分: 108

嗯... 这是在Go中向切片添加元素时人们最常犯的错误。你必须将结果重新赋值给切片。

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

另外,你已经为*MyBox类型定义了AddItem方法,所以调用这个方法应该是box.AddItem(item1)

英文:

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)

答案2

得分: 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))

}

英文:
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

答案3

得分: 17

虽然两种答案都是完全正确的。还有两个更改可以进行:

  1. 摆脱返回语句,因为该方法是为指向结构体的指针调用的,所以切片会自动修改。
  2. 没有必要初始化一个空切片并将其分配给结构体。
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)
}
英文:

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

huangapple
  • 本文由 发表于 2013年8月4日 19:33:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/18042439.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定