go:struct in struct丢失其内容

时间:2015-03-28 08:06:37

标签: arrays struct go

以下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 填写订单中的位置。但是一旦该方法离开,位置列表就会丢失。

为什么数组会丢失其内容?

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

您的loadPos()方法正在使用值接收器(而不是指针),这意味着它在order对象的副本上运行。
因此,当您致电o.loadPos()时,请复制o,然后在该副本上调用loadPos()

解决方案是简单地将接收器更改为指针:

func (o *order) loadPos() {

https://play.golang.org/p/PATpBCZLT7

答案 1 :(得分:2)

扩展Patrick answerGolang FAQ

有更多见解

我应该在值或指针上定义方法吗?

func (s *MyStruct) pointerMethod() { } // method on pointer
func (s MyStruct)  valueMethod()   { } // method on value
  

首先,最重要的是,该方法是否需要修改   接收器?如果是,接收器必须是指针。 (切片和地图   作为参考,所以他们的故事更微妙,但是   在接收器必须的方法中更改切片长度的实例   仍然是一个指针。)在上面的例子中,如果pointerMethod修改   在s的字段中,调用者将看到这些更改,但valueMethod是   用调用者的参数的副本调用(这是定义的   传递一个值,所以改变它使得调用者看不见。

     

其次是效率的考虑。如果接收器很大,a   例如,大结构,使用指针要便宜得多   接收机。

     

接下来是一致性。如果该类型的某些方法必须具有   指针接收器,其余的也应该是,所以方法集是   无论使用何种类型,都是一致的。

对于基本类型,切片和小结构等类型,值 接收器非常便宜,所以除非方法的语义要求 一个指针,一个值接收器是高效和清晰的。