指针诉价值方法

指针方法

即使变量本身不是指针,也可以调用指针方法。

根据 Go Spec

。。。使用可寻址值的指针接收器对非接口方法的引用将自动获取该值的地址:t.Mp 相当于 (&t).Mp

你可以在此示例中看到此内容:

package main

import "fmt"

type Foo struct {
    Bar int
}

func (f *Foo) Increment() {
    f.Bar += 1
}

func main() {
    var f Foo

    // Calling `f.Increment` is automatically changed to `(&f).Increment` by the compiler.
    f = Foo{}
    fmt.Printf("f.Bar is %d\n", f.Bar)
    f.Increment()
    fmt.Printf("f.Bar is %d\n", f.Bar)
    
    // As you can see, calling `(&f).Increment` directly does the same thing.
    f = Foo{}
    fmt.Printf("f.Bar is %d\n", f.Bar)
    (&f).Increment()
    fmt.Printf("f.Bar is %d\n", f.Bar)
}

价值方法

与指针方法类似,即使变量本身不是值,也可以调用值方法。

根据 Go Spec

。。。使用指针对带有值接收器的非接口方法的引用将自动取消引用该指针:pt.Mv 相当于 (*pt).Mv

你可以在此示例中看到此内容:

package main

import "fmt"

type Foo struct {
    Bar int
}

func (f Foo) Increment() {
    f.Bar += 1
}

func main() {
    var p *Foo

    // Calling `p.Increment` is automatically changed to `(*p).Increment` by the compiler.
    // (Note that `*p` is going to remain at 0 because a copy of `*p`, and not the original `*p` are being edited)
    p = &Foo{}
    fmt.Printf("(*p).Bar is %d\n", (*p).Bar)
    p.Increment()
    fmt.Printf("(*p).Bar is %d\n", (*p).Bar)
    
    // As you can see, calling `(*p).Increment` directly does the same thing.
    p = &Foo{}
    fmt.Printf("(*p).Bar is %d\n", (*p).Bar)
    (*p).Increment()
    fmt.Printf("(*p).Bar is %d\n", (*p).Bar)
}

要了解有关指针和值方法的更多信息,请访问方法值Go Spec 部分 ,或参阅有关 Pointers v.Value 值Effective Go 部分

注 1:在 .Bar 之类的选择器之前的*p&f 周围的括号(())用于分组目的,必须保留。

注 2:虽然当指针是方法的接收者时,指针可以转换为值(反之亦然),但当它们是函数内部的参数时,它们不会自动转换为彼此。