对于结构上的方法传递语义的参数是否完全由方法决定,而不是由调用者决定?

时间:2015-06-30 21:53:30

标签: 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的指针是否完全取决于方法的定义,而不是实际传递的内容。

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

1 个答案:

答案 0 :(得分:3)

  

这种行为似乎意味着参数v或指向v的指针是否完全取决于方法的定义,而不是实际传递的内容。

     

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

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

传递给您的方法的内容指针,即使它看起来像v.Mutate() v非指针。原因是:您的v是"可寻址"因此其方法集包括指针类型的方法。有关详细信息,请参阅http://golang.org/ref/spec#Calls。这是一种语法糖。由于v是可寻址的,因此您可以使用其地址&v,并且可以在此指针上调用您的方法(&v).Mutate。这种语法很笨拙,Go会自动为你做可寻址的表达式。

(如果您对这些内容感兴趣,为什么不阅读整个语言规范?可以在3个小时内完成。)