go - 结构体方法的参数传递语义是否完全由方法而不是调用者决定?

标签 go

考虑下面的简单程序,我们在指向 struct Vertex 的指针上定义一个方法,然后用指针调用它。

package main

import (
    "fmt"
)

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Mutate()  {
    v.X = 8
}

func main() {
    v := &Vertex{3, 4}
    v.Mutate()
    fmt.Println(v.X)
}

该程序的输出是 8,这是我们所期望的,因为我们将一个指针传递给一个采用指针的方法。

但是,以下调用的输出也为 8。

func main() {
    v := Vertex{3, 4}
    v.Mutate()
    fmt.Println(v.X)
}

对称地,如果我们重新定义方法Mutate以采用Vertex而不是指针,那么无论传递的是指针还是结构体,突变都会失败。

此行为似乎暗示参数 v 或指向 v 的指针是否传递完全取决于方法的定义,而不是实际传递的内容通过了。

这是正确的解释吗?情况总是如此吗?如果不是,这种行为的正确解释是什么?

最佳答案

This behavior seems to imply that whether the argument v or a pointer to v to passed depends entirely on the definition of the method, rather than on what is actually being passed.

Is this a correct interpretation, and will this always be the case? If not, what is the correct explanation for this behavior?

不,这不正确,但几乎是正确的。

传递给方法的一个指针,即使它看起来像 v.Mutate()v 是一个非指针。原因是:您的 v 是“可寻址的”,因此它的方法集包括指针类型上的方法。请参阅http://golang.org/ref/spec#Calls了解详情。这是一种语法糖。因为 v 是可寻址的,所以您可以获取其地址 &v,并在此指针上调用您的方法,例如 (&v).Mutate。这种语法很笨拙,Go 会自动为您处理可寻址表达式。

(如果你对这些东西感兴趣,为什么不阅读整个语言规范?3小时内就能完成。)

关于go - 结构体方法的参数传递语义是否完全由方法而不是调用者决定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31149191/

相关文章:

go - 在Azure DevOps中为Go设置代码覆盖率

go - struct String() 实现导致堆栈溢出并带有 Sprintf "+"标志

go - 如何添加对象掩码以使用 golang 调用 GetNetworkVlans

go - 如何使用 gin 作为服务器编写 prometheus 导出器指标

Go - 包含 slice 的接口(interface)无法编译

assembly - go 编译器生成的汇编代码中的这种模式是什么?

python - 使用包含消息的信息以安全的方式直接从信使 API 启动 python 脚本

windows - 我可以在构建 Go 程序的同时静态链接一些 DLL 吗?

mongodb - 如何为同名的嵌套字段创建文本索引

go - 如何在Golang中创建kafka消费组?