go: struct 中的数组丢失了它的内容
go: array in struct looses its content
下面的go代码(分享:link)应该在一个顺序中插入两个位置(顺序和位置都是structs:
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填充订单中的位置。但是一旦离开方法,位置列表就会丢失。
为什么数组丢失了它的内容?
如有任何帮助,我们将不胜感激。
您的 loadPos()
方法使用值接收器(而不是指针),这意味着它正在对 order
对象的副本进行操作。
因此,当您调用 o.loadPos()
时,go 正在复制 o
,并在该副本上调用 loadPos()
。
解决办法就是简单的把receiver改成指针:
func (o *order) loadPos() {
延长 Patrick , there is more insight in Golang FAQ
我应该在值或指针上定义方法吗?
func (s *MyStruct) pointerMethod() { } // method on pointer
func (s MyStruct) valueMethod() { } // method on value
First, and most important, does the method need to modify the
receiver? If it does, the receiver must be a pointer. (Slices and maps
act as references, so their story is a little more subtle, but for
instance to change the length of a slice in a method the receiver must
still be a pointer.) In the examples above, if pointerMethod modifies
the fields of s, the caller will see those changes, but valueMethod is
called with a copy of the caller's argument (that's the definition of
passing a value), so changes it makes will be invisible to the caller.
Second is the consideration of efficiency. If the receiver is large, a
big struct for instance, it will be much cheaper to use a pointer
receiver.
Next is consistency. If some of the methods of the type must have
pointer receivers, the rest should too, so the method set is
consistent regardless of how the type is used.
对于基本类型、切片和小型结构等类型,一个值
接收器非常便宜,所以除非方法的语义要求
一个指针,一个值接收者是高效和清晰的。
下面的go代码(分享:link)应该在一个顺序中插入两个位置(顺序和位置都是structs:
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填充订单中的位置。但是一旦离开方法,位置列表就会丢失。
为什么数组丢失了它的内容?
如有任何帮助,我们将不胜感激。
您的 loadPos()
方法使用值接收器(而不是指针),这意味着它正在对 order
对象的副本进行操作。
因此,当您调用 o.loadPos()
时,go 正在复制 o
,并在该副本上调用 loadPos()
。
解决办法就是简单的把receiver改成指针:
func (o *order) loadPos() {
延长 Patrick
我应该在值或指针上定义方法吗?
func (s *MyStruct) pointerMethod() { } // method on pointer
func (s MyStruct) valueMethod() { } // method on value
First, and most important, does the method need to modify the receiver? If it does, the receiver must be a pointer. (Slices and maps act as references, so their story is a little more subtle, but for instance to change the length of a slice in a method the receiver must still be a pointer.) In the examples above, if pointerMethod modifies the fields of s, the caller will see those changes, but valueMethod is called with a copy of the caller's argument (that's the definition of passing a value), so changes it makes will be invisible to the caller.
Second is the consideration of efficiency. If the receiver is large, a big struct for instance, it will be much cheaper to use a pointer receiver.
Next is consistency. If some of the methods of the type must have pointer receivers, the rest should too, so the method set is consistent regardless of how the type is used.
对于基本类型、切片和小型结构等类型,一个值 接收器非常便宜,所以除非方法的语义要求 一个指针,一个值接收者是高效和清晰的。