指標訴價值方法

指標方法

即使變數本身不是指標,也可以呼叫指標方法。

根據 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:雖然當指標是方法的接收者時,指標可以轉換為值(反之亦然),但當它們是函式內部的引數時,它們不會自動轉換為彼此。