一尘不染

Golang指针

go

我目前正在学习使用Go语言编程。我在理解Go指针时遇到了一些困难(并且我的C / C
++现在很遥远…)。例如,在“第52号游览”中(http://tour.golang.org/#52),我读到:

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

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

但是如果不是

func (v *Vertex) Abs() float64 {
[...]
v := &Vertex{3, 4}

我写:

func (v Vertex) Abs() float64 {
[...]
v := Vertex{3, 4}

甚至:

func (v Vertex) Abs() float64 {
[...]
v := &Vertex{3, 4}

反之亦然:

func (v *Vertex) Abs() float64 {
[...]
v := Vertex{3, 4}

我得到了完全相同的结果。有区别吗(在内存方面,等等)?


阅读 363

收藏
2020-07-02

共1个答案

一尘不染

您的示例使用两种Go语言规则:

  1. 可以从具有值接收器的方法派生具有指针接收器的方法。这样func (v Vertex) Abs() float64将自动生成一个附加的方法实现:
    func (v Vertex) Abs() float64 { return math.Sqrt(v.X*v.X+v.Y*v.Y) }
    

    func (v Vertex) Abs() float64 { return Vertex.Abs(v) } // GENERATED METHOD

编译器将自动找到生成的方法:

    v := &Vertex{3, 4}
v.Abs()  // calls the generated method
  1. Go可以自动获取变量的地址。在以下示例中:
        func (v *Vertex) Abs() float64 { return math.Sqrt(v.X*v.X+v.Y*v.Y) }
    func main() {
        v := Vertex{3, 4}
        v.Abs()
    }

该表达式v.Abs()等效于以下代码:

    vp := &v
vp.Abs()
2020-07-02