Suche…


Syntax

  • Zeiger: = & variable // Zeiger aus Variable holen
  • variable: = * pointer // Variable vom Zeiger abrufen
  • * pointer = value // Wert von Variable durch den Zeiger setzen
  • pointer: = new (Struct) // Zeiger der neuen Struktur abrufen

Grundlegende Zeiger

Go unterstützt Zeiger , mit denen Sie Verweise auf Werte und Datensätze in Ihrem Programm übergeben können.

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
}

Sobald diese Funktionen definiert sind, können Sie Folgendes tun:

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
}

Versuchen Sie diesen Code

Zeiger v. Wertmethoden

Zeiger-Methoden

Zeigermethoden können auch aufgerufen werden, wenn die Variable selbst kein Zeiger ist.

Nach der Go-Spezifikation

. . . Ein Verweis auf eine Methode ohne Schnittstelle, bei der ein t.Mp einen adressierbaren Wert verwendet, übernimmt automatisch die Adresse dieses Werts: t.Mp entspricht (&t).Mp .

Sie können dies in diesem Beispiel sehen:

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

Spiel es

Wertmethoden

Ähnlich wie bei Pointer-Methoden können Value-Methoden aufgerufen werden, auch wenn die Variable selbst kein Wert ist.

Nach der Go-Spezifikation

. . . Ein Verweis auf eine Methode ohne Schnittstelle, bei der ein pt.Mv einen Zeiger verwendet, dereferenziert diesen Zeiger automatisch: pt.Mv entspricht (*pt).Mv .

Sie können dies in diesem Beispiel sehen:

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

Spiel es


Weitere Informationen zu Pointer- und Value-Methoden finden Sie im Abschnitt "Go-Spezifikation" unter "Methodenwerte" oder im Abschnitt "Effective Go" über "Pointer vs. Values" .


Hinweis 1: Die Klammern ( () ) um *p und &f vor Selektoren wie .Bar dienen zur Gruppierung und müssen beibehalten werden.

Hinweis 2: Obwohl Zeiger in Werte umgewandelt werden können (und umgekehrt), wenn sie die Empfänger einer Methode sind, werden sie nicht automatisch in einander konvertiert, wenn sie Argumente innerhalb einer Funktion sind.

Dereferenzierungszeiger

Zeiger können durch Hinzufügen eines Sterns * vor einem Zeiger dereferenziert werden.

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
}

Slices sind Zeiger auf Arraysegmente

Slices sind Zeiger auf Arrays mit der Länge des Segments und seiner Kapazität. Sie verhalten sich als Zeiger und weisen ihren Wert einem anderen Slice zu. Sie weisen die Speicheradresse zu. Um ein Stück Wert auf einen anderen zu kopieren, verwenden Sie die integrierten Kopierfunktion: func copy(dst, src []Type) int (liefert die Menge der kopierten Elemente).

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
}

Einfache Zeiger

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
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow