Tho*_*don 3 struct append go slice
我正在尝试将值附加到golang切片,如果在第一个方法中调用它,代码就可以工作,但如果此方法调用另一个方法,则代码似乎失败了.
示例(Test3是我最初尝试做的):
package main
import (
"fmt"
)
// This works
type Test1 struct {
all []int
}
func (c Test1) run() []int {
for i := 0; i < 2; i++ {
c.all = append(c.all, i)
}
return c.all
}
// This works
var gloabl_all []int
type Test2 struct {}
func (c Test2) run() []int {
c.combo()
return gloabl_all
}
func (c Test2) combo() {
for i := 0; i < 2; i++ {
gloabl_all = append(gloabl_all, i)
}
}
// This doesn't
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() {
test1 := &Test1{}
fmt.Println("Test1 final:", test1.run(), "\n")
test2 := &Test2{}
fmt.Println("Test2 final:", test2.run(), "\n")
test3 := &Test3{}
fmt.Println("Test3 final:", test3.run())
}
Run Code Online (Sandbox Code Playgroud)
这输出:
Test1 final: [0 1]
Test2 final: [0 1]
Test3 step 1 [0]
Test3 step 2 [0 1]
Test3 final: []
Run Code Online (Sandbox Code Playgroud)
游乐场副本:https://play.golang.org/p/upEXINUvNu
任何帮助将不胜感激!
Go中的所有内容都按值传递.并且复制由传递的值组成.
Test3.combo() 有值(非指针)接收器:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
这意味着当Test3.combo()从Test3.run()like 调用时c.combo(),复制(由c类型Test3).该combo()方法在副本上运行.它正确地附加了2个数字Test3.all,但是当此方法返回时,将丢弃该副本.
因此,当Test3.run()返回时c.all,它返回一个empty(nil)切片,因为Test3.combo()附加的切片是一个副本的字段,并且已被丢弃.
解决方案:只需使用指针接收器:
func (c *Test3) combo() {
for i := 0; i < 2; i++ {
c.all = append(c.all, i)
fmt.Println("Test3 step", i + 1, c.all)
}
}
Run Code Online (Sandbox Code Playgroud)
输出(在Go Playground上试试):
Test1 final: [0 1]
Test2 final: [0 1]
Test3 step 1 [0]
Test3 step 2 [0 1]
Test3 final: [0 1]
Run Code Online (Sandbox Code Playgroud)
注意*接收器中的星号:func (c *Test3) combo().通过添加它,你使接收器成为一个指针,所以当combo()调用它时,它只接收一个指向类型值的指针Test3,它将修改指向的值,即Test3.run()具有的值,因此当combo()返回时,更改不会丢失.