golang deep是否复制整个接收器值?

golang deep是否复制整个接收器值?,go,Go,我几乎可以肯定,但我想100%肯定。因为这在JS/PHP之后看起来很奇怪 type Vertex struct { X, Y float64 } func (v Vertex) Scale(f float64) { v.X = v.X * f v.Y = v.Y * f } 那么,在每次调用Scale时,是否会生成v Vertex参数的深度副本(强调这点)?因此,我们应该使用指针接收器而不是值接收器,以避免深度复制 这同样适用于参数,对吗?还有哪些地方会进行复制?是的

我几乎可以肯定,但我想100%肯定。因为这在JS/PHP之后看起来很奇怪

type Vertex struct {
    X, Y float64
}

func (v Vertex) Scale(f float64) {
    v.X = v.X * f
    v.Y = v.Y * f
}
那么,在每次调用
Scale
时,是否会生成
v Vertex
参数的深度副本(强调这点)?因此,我们应该使用指针接收器而不是值接收器,以避免深度复制


这同样适用于参数,对吗?还有哪些地方会进行复制?

是的,会进行复制。如果值很大,您关心避免复制,并且没有其他考虑(例如出于各种原因需要复制),请使用指针接收器

on值与指针接收器

请注意,复制是创建的,但您说的是“深度复制”,所以在这里要小心-通常深度复制意味着递归复制,包括指针指向的内容(例如复制整个树)。这里的副本是浅薄的副本。如果
Vertex
具有指针字段,则将复制这些指针的值,但不会复制它们指向的内容。在Go online中有大量关于浅拷贝与深拷贝的讨论;例如如果存在结构字段,这些字段的值也将被复制,因此它在结构嵌套的意义上是“深的”,而在指针的意义上不是“深的”

[Go]深度复制整个接收器值吗


否。Go不执行深度复制,仅执行浅层复制

在Go中,所有参数都是按值传递的,就像通过赋值给参数或接收器一样


因此,我们应该使用指针接收器而不是值接收器


不正确

例如,从Go标准库:

时间以纳秒精度表示时间中的一个瞬间

使用时间的程序通常应将时间作为值存储和传递, 不是指针。也就是说,时间变量和结构字段应该是 键入time.time,而不是*time.time


哇,Eli Bendersky,我从你在Eli.thegreenplace.net上的精彩文章中学到了语法分析(我读了20遍)。非常感谢。那么同样的情况也适用于参数?Eli,我很抱歉,如果我没有阅读文档,而是麻烦了太多(我确实这么做了,但我经常错过一些东西),但是还有哪些地方会发生复制呢?我将把这一点添加到问题中。您可以在这里将接收器视为一种特殊类型的参数(如Python中的
self
)。通过值copies参数和receiversy,结构将被复制,但这不是通常所说的“深度复制”。这是一个简单的结构,没有内部指针。只有传入的值才会被复制。@JimB如果它不是简单结构(而是嵌套结构),那么它将是深度复制,对吗?“golang深度复制整个接收方值吗?”不,您得到的只是一个“浅”复制。@Nurbolpysbayev:嵌套结构值会被复制,因为它是值的一部分。考虑一下结构的内存布局,以及传入的内容。指针不会被取消引用,因此只会复制指针值。映射和切片也是如此。@mkopriva我想你的意思是指针字段将被复制为指针,而不是它们指向的值。但值字段将被完全复制。随着时间的推移,这是一个有趣的例子。目前我还没有完全理解它,但我确信,在对时间包进行一些实验之后,我很快就会得到它,这个例子会派上用场。@Nurbollypysbayev:
time.time
是一个小的
结构。指针引入了一定程度的间接性,即成本。现代硬件执行许多优化。
import "time"
type Time struct {
  wall uint64
  ext  int64
  loc *Location
}