【问题标题】:When a receiver method T cannot take *T?当接收方方法 T 不能采用 *T 时?
【发布时间】:2019-11-04 07:07:18
【问题描述】:

围棋官方网站writes as follows

正如 Go 规范所说,类型 T 的方法集包括 所有接收器类型为 T 的方法,而相应的接收器类型为 T 指针类型 *T 由所有带有接收者 *T 或 T 的方法组成。 表示 *T 的方法集包含 T 的方法集,但不包含相反的方法。

出现这种区别是因为如果接口值包含 指针 *T,方法调用可以通过解引用 指针,但如果接口值包含值 T,则不存在 方法调用获取指针的安​​全方法。 (这样做将允许 修改接口内值内容的方法, 这是语言规范所不允许的。)

即使编译器可以将值的地址 传递给方法,如果方法修改了值,更改将 迷失在调用者中。

我的问题是,当不能编译器将一个值传递给指针接收器值时?

【问题讨论】:

  • stackoverflow.com/q/40828156/1256452:为什么接口不实现带有指针引用的方法,而直接访问仍然是可能的? - 这是否涵盖了您想知道的情况?
  • "什么时候编译器不能将值传递给指针接收器值?"正如从规范中引用的第二段中所解释的那样:总是。如果您对规范中标记为粗体的部分感兴趣:有些东西是不可寻址的,例如a function:不能取函数的地址。 (如果你是 Go 新手:这很无趣。)

标签: go


【解决方案1】:

Addressable 定义在https://golang.org/ref/spec#Address_operators:

对于类型为 T 的操作数 x,地址操作 &x 生成指向 x 的 *T 类型的指针。操作数必须是可寻址,即变量、指针间接或切片索引操作;或可寻址结构操作数的字段选择器;或可寻址数组的数组索引操作。作为可寻址性要求的一个例外,x 也可以是(可能是带括号的)复合文字。

反例包括地图值和函数:

func f() {}

func main() {
    var m map[string]string
    p1 := &m["foo"] // cannot take the address of m["foo"]
    p2 := &f        // cannot take the address of f
}

【讨论】:

    猜你喜欢
    • 2013-10-26
    • 1970-01-01
    • 2012-05-14
    • 1970-01-01
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 2012-05-27
    • 1970-01-01
    相关资源
    最近更新 更多