带有指针接收器的
6.2方法
如果命名类型T的所有方法都具有T本身的接收器类型(不是*T ),则复制该类型的实例是安全的;调用其任何方法必然会生成副本。例如,time.Duration值被大量复制,包括作为参数复制到函数。但是,如果任何方法都有指针接收器,则应该避免复制T的实例,因为这样做可能违反内部不变量。例如,复制bytes.Buffer的一个实例将导致原始和复制到别名(§2.3.2 )相同的底层字节数组。随后的方法调用将产生不可预知的效果。
( Go编程语言Alan A. Donovan·Brian W. Kernighan)
我理解引号的一般含义,但我想知道复制这种类型的实例是否正确。
如果一个结构有一个切片/map字段,那么所有副本都会接收到支持数组/hashmap的指针的副本,所以仍然可以对这些数据结构进行变异。
即使所有方法都可以使用值接收者定义,我们也可以打破结构的内部状态。
我明白为什么会发生这种情况,但这种可能性是否与上面那一段所写的相矛盾?
复制值可能会产生不必要的后果,而不管方法接收者是什么,也取决于字段类型。
我在这里错过了什么?
package main
import "fmt"
type T struct {
s []string
}
func main() {
original := T{s: []string{"original"}}
copycat := original
copycat.s[0] = "copycat"
fmt.Println(original.s[0] == "copycat") // true
}发布于 2022-02-03 18:27:02
我既不是Donovan也不是Kernighan,所以我不能明确地说出他们在这里试图沟通的内容,但我的理解不是“使用值接收者使复制安全”,而是“使用值接收器表示复制是安全的”。正确的是,任何指针字段,或任何包含指针字段(包括切片和映射)的字段,都将使复制不安全;我相信,作者试图了解的是,使用值接收者的API正在向其使用者指示不存在此类字段。
https://stackoverflow.com/questions/70975907
复制相似问题