以下go代码(共享:link)应该在一个顺序中插入两个位置(顺序和位置都是 struct s:
package main
import "fmt"
type orderPosition struct{
art string
qty string
}
type order struct{
posList []orderPosition
}
func main() {
o := new(order)
o.loadPos()
fmt.Printf("# pos: %d\n",len(o.posList))
}
func (o order) loadPos() {
o.posList = append(o.posList, orderPosition {art: "art 1", qty: "2 pc"})
o.posList = append(o.posList, orderPosition {art: "art 2", qty: "7 pc"})
fmt.Printf("# pos: %d\n",len(o.posList))
}
输出结果为:
# pos: 2
# pos: 0
方法 loadPos 填写订单中的位置。但是一旦该方法离开,位置列表就会丢失。
为什么数组会丢失其内容?
非常感谢任何帮助。
答案 0 :(得分:3)
您的loadPos()
方法正在使用值接收器(而不是指针),这意味着它在order
对象的副本上运行。
因此,当您致电o.loadPos()
时,请复制o
,然后在该副本上调用loadPos()
。
解决方案是简单地将接收器更改为指针:
func (o *order) loadPos() {
答案 1 :(得分:2)
扩展Patrick answer,Golang FAQ
有更多见解我应该在值或指针上定义方法吗?
func (s *MyStruct) pointerMethod() { } // method on pointer
func (s MyStruct) valueMethod() { } // method on value
首先,最重要的是,该方法是否需要修改 接收器?如果是,接收器必须是指针。 (切片和地图 作为参考,所以他们的故事更微妙,但是 在接收器必须的方法中更改切片长度的实例 仍然是一个指针。)在上面的例子中,如果pointerMethod修改 在s的字段中,调用者将看到这些更改,但valueMethod是 用调用者的参数的副本调用(这是定义的 传递一个值,所以改变它使得调用者看不见。
其次是效率的考虑。如果接收器很大,a 例如,大结构,使用指针要便宜得多 接收机。
接下来是一致性。如果该类型的某些方法必须具有 指针接收器,其余的也应该是,所以方法集是 无论使用何种类型,都是一致的。
对于基本类型,切片和小结构等类型,值 接收器非常便宜,所以除非方法的语义要求 一个指针,一个值接收器是高效和清晰的。