首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >更改结构的片字段,即使所有方法都是用值接收器定义的

更改结构的片字段,即使所有方法都是用值接收器定义的
EN

Stack Overflow用户
提问于 2022-02-03 17:45:22
回答 1查看 238关注 0票数 1

带有指针接收器的

6.2方法

如果命名类型T的所有方法都具有T本身的接收器类型(不是*T ),则复制该类型的实例是安全的;调用其任何方法必然会生成副本。例如,time.Duration值被大量复制,包括作为参数复制到函数。但是,如果任何方法都有指针接收器,则应该避免复制T的实例,因为这样做可能违反内部不变量。例如,复制bytes.Buffer的一个实例将导致原始和复制到别名(§2.3.2 )相同的底层字节数组。随后的方法调用将产生不可预知的效果。

( Go编程语言Alan A. Donovan·Brian W. Kernighan)

我理解引号的一般含义,但我想知道复制这种类型的实例是否正确。

如果一个结构有一个切片/map字段,那么所有副本都会接收到支持数组/hashmap的指针的副本,所以仍然可以对这些数据结构进行变异。

即使所有方法都可以使用值接收者定义,我们也可以打破结构的内部状态。

我明白为什么会发生这种情况,但这种可能性是否与上面那一段所写的相矛盾?

复制值可能会产生不必要的后果,而不管方法接收者是什么,也取决于字段类型。

我在这里错过了什么?

代码语言:javascript
复制
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
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-03 18:27:02

我既不是Donovan也不是Kernighan,所以我不能明确地说出他们在这里试图沟通的内容,但我的理解不是“使用值接收者使复制安全”,而是“使用值接收器表示复制是安全的”。正确的是,任何指针字段,或任何包含指针字段(包括切片和映射)的字段,都将使复制不安全;我相信,作者试图了解的是,使用值接收者的API正在向其使用者指示不存在此类字段。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70975907

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档