\n\n6.2 使用指针接收器的方法
\n如果命名类型 T 的所有方法都有 T 本身的接收者类型\n(不是 *T ),则复制该类型的实例是安全的;调用任何方法都必然会生成一个副本。例如,time.Duration\n值可以自由复制,包括作为函数的参数。但是,如果任何方法有指针接收器,则应避免复制 T 的实例,因为这样做可能会违反内部不变量。例如,复制 bytes.Buffer 的实例将导致原始\n和副本别名 ( \xc2\xa72.3.2 ) 相同的底层字节数组。\n后续方法调用将产生不可预测的影响。
\n(Go 编程语言 Alan AA Donovan \xc2\xb7 Brian W. Kernighan)
\n
我理解这句话的一般含义,但我想知道复制该类型的实例是安全的是否正确。
\n如果结构体具有切片/映射字段,则所有副本都会收到自己的指向后备数组/哈希图的指针副本,因此仍然可以更改这些数据结构。
\n尽管所有方法都可以使用值接收器定义,但我们可以破坏结构的内部状态。
\n我明白为什么会发生这种情况,但是这种可能性是否与上面段落中所写的内容相矛盾?
\n无论方法接收者如何,复制值都可能会产生不良后果,并且还取决于字段类型。
\n我在这里缺少什么?
\npackage main\n\nimport "fmt"\n\ntype T struct {\n s []string\n}\n\nfunc main() {\n original := T{s: []string{"original"}}\n copycat := original\n copycat.s[0] = "copycat"\n fmt.Println(original.s[0] == "copycat") // true\n}\nRun Code Online (Sandbox Code Playgroud)\n
我既不是 Donovan,也不是 Kernighan,所以我不能明确地说出他们在这里试图传达的内容,但我的理解不是“使用值接收器使复制安全”,而是“使用值接收器表明复制是安全的”。您是正确的,任何指针字段或任何包含指针字段的字段(包括切片和映射)都会使复制不安全;我相信作者试图传达的是,使用值接收器的 API 向其消费者表明不存在这样的字段。
| 归档时间: |
|
| 查看次数: |
510 次 |
| 最近记录: |