Recherche…


Syntaxe

  • pointeur: = & variable // obtient le pointeur de la variable
  • variable: = * pointeur // obtient la variable du pointeur
  • * pointeur = valeur // définir la valeur de la variable via le pointeur
  • pointeur: = new (Struct) // récupère le pointeur de la nouvelle structure

Pointeurs de base

Go prend en charge les pointeurs , vous permettant de transmettre des références aux valeurs et aux enregistrements de votre programme.

package main

import "fmt"

// We'll show how pointers work in contrast to values with
// 2 functions: `zeroval` and `zeroptr`. `zeroval` has an
// `int` parameter, so arguments will be passed to it by
// value. `zeroval` will get a copy of `ival` distinct
// from the one in the calling function.
func zeroval(ival int) {
    ival = 0
}

// `zeroptr` in contrast has an `*int` parameter, meaning
// that it takes an `int` pointer. The `*iptr` code in the
// function body then _dereferences_ the pointer from its
// memory address to the current value at that address.
// Assigning a value to a dereferenced pointer changes the
// value at the referenced address.
func zeroptr(iptr *int) {
    *iptr = 0
}

Une fois ces fonctions définies, vous pouvez effectuer les opérations suivantes:

func main() {
    i := 1
    fmt.Println("initial:", i) // initial: 1

    zeroval(i)
    fmt.Println("zeroval:", i) // zeroval: 1
    // `i` is still equal to 1 because `zeroval` edited
    // a "copy" of `i`, not the original.

    // The `&i` syntax gives the memory address of `i`,
    // i.e. a pointer to `i`. When calling `zeroptr`,
    // it will edit the "original" `i`.
    zeroptr(&i)
    fmt.Println("zeroptr:", i) // zeroptr: 0

    // Pointers can be printed too.
    fmt.Println("pointer:", &i) // pointer: 0x10434114
}

Essayez ce code

Pointeur v. Méthodes de valeur

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.

Dereferencing Pointers

Les pointeurs peuvent être déréférencés en ajoutant un astérisque * avant un pointeur.

package main

import (
    "fmt"
)

type Person struct {
    Name string
}

func main() {
    c := new(Person) // returns pointer
    c.Name = "Catherine"
    fmt.Println(c.Name) // prints: Catherine
    d := c
    d.Name = "Daniel"
    fmt.Println(c.Name) // prints: Daniel
    // Adding an Asterix before a pointer dereferences the pointer
    i := *d
    i.Name = "Ines"
    fmt.Println(c.Name) // prints: Daniel
    fmt.Println(d.Name) // prints: Daniel
    fmt.Println(i.Name) // prints: Ines
}

Les tranches sont des pointeurs vers des segments de tableau

Les tranches sont des pointeurs vers les tableaux, avec la longueur du segment et sa capacité. Ils se comportent comme des pointeurs et en attribuant leur valeur à une autre tranche, ils attribueront l'adresse mémoire. Pour copier une valeur de tranche dans une autre, utilisez la fonction de copie intégrée: func copy(dst, src []Type) int (renvoie la quantité d'éléments copiés).

package main

import (
    "fmt"
)

func main() {
    x := []byte{'a', 'b', 'c'}
    fmt.Printf("%s", x)       // prints: abc
    y := x
    y[0], y[1], y[2] = 'x', 'y', 'z'
    fmt.Printf("%s", x)       // prints: xyz
    z := make([]byte, len(x))
    // To copy the value to another slice, but 
    // but not the memory address use copy:
    _ = copy(z, x)            // returns count of items copied
    fmt.Printf("%s", z)       // prints: xyz
    z[0], z[1], z[2] = 'a', 'b', 'c'
    fmt.Printf("%s", x)       // prints: xyz
    fmt.Printf("%s", z)       // prints: abc
}

Pointeurs simples

func swap(x, y *int) {
  *x, *y = *y, *x
}

func main() {
  x := int(1)
  y := int(2)
  // variable addresses
  swap(&x, &y)
  fmt.Println(x, y)
}


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow