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

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

Go - append to slice in struct

问题

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

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. type MyBoxItem struct {
  6. Name string
  7. }
  8. type MyBox struct {
  9. Items []MyBoxItem
  10. }
  11. func (box *MyBox) AddItem(item MyBoxItem) []MyBoxItem {
  12. return append(box.Items, item)
  13. }
  14. func main() {
  15. item1 := MyBoxItem{Name: "Test Item 1"}
  16. item2 := MyBoxItem{Name: "Test Item 2"}
  17. items := []MyBoxItem{}
  18. box := MyBox{items}
  19. AddItem(box, item1) // 这是我卡住的地方
  20. fmt.Println(len(box.Items))
  21. }

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

英文:

I am trying to implement 2 simple structs as follows:

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. type MyBoxItem struct {
  6. Name string
  7. }
  8. type MyBox struct {
  9. Items []MyBoxItem
  10. }
  11. func (box *MyBox) AddItem(item MyBoxItem) []MyBoxItem {
  12. return append(box.Items, item)
  13. }
  14. func main() {
  15. item1 := MyBoxItem{Name: "Test Item 1"}
  16. item2 := MyBoxItem{Name: "Test Item 2"}
  17. items := []MyBoxItem{}
  18. box := MyBox{items}
  19. AddItem(box, item1) // This is where i am stuck
  20. fmt.Println(len(box.Items))
  21. }

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中向切片添加元素时人们最常犯的错误。你必须将结果重新赋值给切片。

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

另外,你已经为*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.

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

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() {

  1. item1 := MyBoxItem{Name: "Test Item 1"}
  2. items := []MyBoxItem{}
  3. box := MyBox{items}
  4. box.AddItem(item1)
  5. fmt.Println(len(box.Items))

}

英文:
  1. package main
  2. import (
  3. "fmt"
  4. )
  5. type MyBoxItem struct {
  6. Name string
  7. }
  8. type MyBox struct {
  9. Items []MyBoxItem
  10. }
  11. func (box *MyBox) AddItem(item MyBoxItem) []MyBoxItem {
  12. box.Items = append(box.Items, item)
  13. return box.Items
  14. }
  15. func main() {
  16. item1 := MyBoxItem{Name: "Test Item 1"}
  17. items := []MyBoxItem{}
  18. box := MyBox{items}
  19. box.AddItem(item1)
  20. fmt.Println(len(box.Items))
  21. }

Playground


Output:

  1. 1

答案3

得分: 17

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

  1. 摆脱返回语句,因为该方法是为指向结构体的指针调用的,所以切片会自动修改。
  2. 没有必要初始化一个空切片并将其分配给结构体。
  1. package main
  2. import (
  3. "fmt"
  4. )
  5. type MyBoxItem struct {
  6. Name string
  7. }
  8. type MyBox struct {
  9. Items []MyBoxItem
  10. }
  11. func (box *MyBox) AddItem(item MyBoxItem) {
  12. box.Items = append(box.Items, item)
  13. }
  14. func main() {
  15. item1 := MyBoxItem{Name: "Test Item 1"}
  16. item2 := MyBoxItem{Name: "Test Item 2"}
  17. box := MyBox{}
  18. box.AddItem(item1)
  19. box.AddItem(item2)
  20. // checking the output
  21. fmt.Println(len(box.Items))
  22. fmt.Println(box.Items)
  23. }
英文:

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
  1. package main
  2. import (
  3. "fmt"
  4. )
  5. type MyBoxItem struct {
  6. Name string
  7. }
  8. type MyBox struct {
  9. Items []MyBoxItem
  10. }
  11. func (box *MyBox) AddItem(item MyBoxItem) {
  12. box.Items = append(box.Items, item)
  13. }
  14. func main() {
  15. item1 := MyBoxItem{Name: "Test Item 1"}
  16. item2 := MyBoxItem{Name: "Test Item 2"}
  17. box := MyBox{}
  18. box.AddItem(item1)
  19. box.AddItem(item2)
  20. // checking the output
  21. fmt.Println(len(box.Items))
  22. fmt.Println(box.Items)
  23. }

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:

确定