Go Pointeur v. Méthodes de valeur


Exemple

Méthodes de pointeur

Les méthodes de pointage peuvent être appelées même si la variable n'est pas elle-même un pointeur.

Selon le Go Spec ,

. . . une référence à une méthode sans interface avec un récepteur de pointeur utilisant une valeur adressable prendra automatiquement l'adresse de cette valeur: t.Mp est équivalent à (&t).Mp .

Vous pouvez voir cela dans cet exemple:

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)
}

Joue-le

Méthodes de valeur

Comme pour les méthodes de pointage, les méthodes de valeur peuvent être appelées même si la variable n'est pas elle-même une valeur.

Selon le Go Spec ,

. . . une référence à une méthode sans interface avec un récepteur de valeur utilisant un pointeur déréférencera automatiquement ce pointeur: pt.Mv est équivalent à (*pt).Mv .

Vous pouvez voir cela dans cet exemple:

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)
}

Joue-le


Pour en savoir plus sur les méthodes de pointeur et de valeur, consultez la section Spécification de la méthode sur les valeurs de la méthode , ou consultez la section Mise en oeuvre effective concernant Pointers v. Values .


Note 1: La parenthèse ( () ) autour de *p et &f avant que les sélecteurs comme .Bar soient .Bar à des fins de regroupement et doivent être conservés.

Note 2: Bien que les pointeurs puissent être convertis en valeurs (et vice-versa) lorsqu'ils sont les récepteurs d'une méthode, ils ne sont pas convertis automatiquement entre eux lorsqu'ils sont des arguments à l'intérieur d'une fonction.