为什么我不能追加到 Golang 中结构体属性的切片?
在 Golang 中,一切都是按值传递的,这意味着只要将对象作为参数传递给函数,就会创建对象的副本。当尝试附加到作为结构体属性的切片时,这可能会导致意外行为。
问题:Test3
考虑以下示例:
package main import "fmt" type Test3 struct { all []int } func (c Test3) run() []int { c.combo() return c.all } func (c Test3) combo() { for i := 0; i < 2; i++ { c.all = append(c.all, i) fmt.Println("Test3 step", i+1, c.all) } } func main() { test3 := &Test3{} fmt.Println("Test3 final:", test3.run()) }
当您调用 test3.run() 时,它会创建 test3 的副本并将其传递给运行。 run 方法然后调用combo,它将两个值附加到c.all。但是,当 run 返回时,对 c.all 的更改会丢失,因为 test3 的副本被丢弃。这会导致返回空切片,如输出所示:
Test3 step 1 [0] Test3 step 2 [0 1] Test3 final: []
解决方案:使用指针接收器
要解决此问题,您需要将指针接收器用于组合方法。这告诉编译器传递指向 Test3 值的指针而不是副本。
func (c *Test3) combo() { for i := 0; i < 2; i++ { c.all = append(c.all, i) fmt.Println("Test3 step", i+1, c.all) } }
使用指针接收器,对组合中的 c.all 所做的更改将直接应用于原始 Test3 值,因为它是通过引用传递的。这会产生正确的输出:
Test3 step 1 [0] Test3 step 2 [0 1] Test3 final: [0 1]
通过理解按值传递的概念并适当使用指针接收器,您可以在使用 Golang 结构体中的切片时避免意外行为。
以上是为什么除非使用指针接收器,否则附加到 Golang 结构体方法中的切片不起作用?的详细内容。更多信息请关注PHP中文网其他相关文章!