Zoeken…


Syntaxis

  • pointer: = & variable // haal pointer van variabele
  • variable: = * pointer // haal variabele van pointer
  • * pointer = waarde // ingestelde waarde van variabele via de aanwijzer
  • pointer: = new (Struct) // krijg pointer van nieuwe struct

Basiswijzers

Go ondersteunt verwijzingen , zodat u verwijzingen naar waarden en records binnen uw programma kunt doorgeven.

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
}

Nadat deze functies zijn gedefinieerd, kunt u het volgende doen:

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
}

Probeer deze code

Aanwijzer v. Waardemethoden

Aanwijzer methoden

Aanwijsmethoden kunnen worden opgeroepen, zelfs als de variabele zelf geen aanwijzer is.

Volgens de Go Spec ,

. . . een verwijzing naar een niet-interfacemethode met een t.Mp die een adresseerbare waarde gebruikt, krijgt automatisch het adres van die waarde: t.Mp is gelijk aan (&t).Mp .

Je kunt dit in dit voorbeeld zien:

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

Speel het

Waarde methoden

Net als pointermethoden kunnen waardemethoden worden aangeroepen, zelfs als de variabele zelf geen waarde is.

Volgens de Go Spec ,

. . . een verwijzing naar een niet-interfacemethode met een waardeontvanger die een pointer gebruikt, zal automatisch die pointer pt.Mv : pt.Mv is gelijk aan (*pt).Mv .

Je kunt dit in dit voorbeeld zien:

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

Speel het


Voor meer informatie over aanwijzer- en waardemethoden gaat u naar het gedeelte Specificatie over Methode waarden of raadpleegt u het gedeelte Effectieve Go over Aanwijzers v. Waarden .


Opmerking 1: De haakjes ( () ) rond *p en &f vóór selectors zoals .Bar zijn er voor groeperingsdoeleinden en moeten worden bewaard.

Opmerking 2: Hoewel aanwijzers kunnen worden omgezet in waarden (en omgekeerd) wanneer ze de ontvangers zijn voor een methode, worden ze niet automatisch naar elkaar geconverteerd als ze argumenten binnen een functie zijn.

Verwijzingen naar verwijzingen

Aanwijzers kunnen worden verwijderd door een sterretje * toe te voegen vóór een aanwijzer.

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
}

Segmenten zijn verwijzingen naar matrixsegmenten

Segmenten zijn verwijzingen naar arrays, met de lengte van het segment en zijn capaciteit. Ze gedragen zich als pointers en als ze hun waarde toewijzen aan een ander segment, wordt het geheugenadres toegewezen. Gebruik de ingebouwde kopieerfunctie om een segmentwaarde naar een ander te kopiëren : func copy(dst, src []Type) int (retourneert het aantal gekopieerde items).

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
}

Simple Pointers

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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow