Skip to content

Go-Zeiger

Zeiger in Go sind ähnlich wie in C, aber einfacher. Zeiger werden verwendet, um Speicheradressen zu speichern.

Was ist ein Zeiger?

Ein Zeiger ist eine Variable, die die Speicheradresse einer anderen Variable speichert. In Go wird ein Zeiger mit * deklariert.

go
var p *int

In diesem Beispiel ist p ein Zeiger auf einen int-Wert.

Adressoperator

Der Adressoperator & wird verwendet, um die Adresse einer Variable zu erhalten.

go
func main() {
   a := 42
   p := &a
   fmt.Printf("Adresse von a: %p\n", p)
}

Dereferenzierung

Der Dereferenzierungsoperator * wird verwendet, um auf den Wert zuzugreifen, auf den der Zeiger zeigt.

go
func main() {
   a := 42
   p := &a
   fmt.Println(*p) // 42
   *p = 100
   fmt.Println(a) // 100
}

new-Funktion

Die new-Funktion allokiert Speicher für einen Typ und gibt einen Zeiger darauf zurück.

go
func main() {
   p := new(int)
   *p = 42
   fmt.Println(*p) // 42
}

Zeiger auf Zeiger

Ein Zeiger kann auch auf einen anderen Zeiger zeigen.

go
func main() {
   a := 42
   p := &a
   pp := &p
   fmt.Println(**pp) // 42
}

Zeiger und Funktionen

Zeiger können an Funktionen übergeben werden, um Werte zu ändern.

go
func main() {
   a := 42
   modify(&a)
   fmt.Println(a) // 100
}

func modify(p *int) {
   *p = 100
}

Zeiger und Strukturen

Zeiger werden häufig mit Strukturen verwendet, um Kopien zu vermeiden.

go
type Person struct {
   Name string
   Age  int
}

func main() {
   p := Person{Name: "Alice", Age: 25}
   modifyPerson(&p)
   fmt.Println(p.Name) // Bob
}

func modifyPerson(p *Person) {
   p.Name = "Bob"
}

nil Zeiger

Ein Zeiger, der nicht initialisiert wurde, hat den Wert nil.

go
func main() {
   var p *int
   fmt.Println(p) // <nil>
   fmt.Println(p == nil) // true
}

Zeigerarithmetik

Go unterstützt keine Zeigerarithmetik wie C. Sie können nicht auf Zeigern rechnen.

go
func main() {
   a := 42
   p := &a
   // p++ // Fehler: invalid operation
}

Vergleich von Zeigern

Zeiger können mit == und != verglichen werden.

go
func main() {
   a := 42
   p1 := &a
   p2 := &a
   p3 := new(int)
   fmt.Println(p1 == p2) // true
   fmt.Println(p1 == p3) // false
}

Wann Zeiger verwenden?

Zeiger sollten in folgenden Fällen verwendet werden:

  1. Wenn Sie den Wert einer Variable in einer Funktion ändern möchten
  2. Wenn Sie vermeiden möchten, große Strukturen zu kopieren
  3. Wenn Sie nullable Werte benötigen
go
type Person struct {
   Name string
   Age  *int // Age kann nil sein
}

Zeiger und Slices

Slices sind intern Zeiger auf Arrays. Wenn Sie einen Slice an eine Funktion übergeben, wird nur ein Zeiger kopiert, nicht die gesamten Daten.

go
func main() {
   s := []int{1, 2, 3}
   modifySlice(s)
   fmt.Println(s) // [100 2 3]
}

func modifySlice(s []int) {
   s[0] = 100
}

Zeiger und Maps

Maps sind intern Referenztypen. Wenn Sie eine Map an eine Funktion übergeben, wird nur ein Zeiger kopiert.

go
func main() {
   m := map[string]int{"a": 1}
   modifyMap(m)
   fmt.Println(m) // map[a:100]
}

func modifyMap(m map[string]int) {
   m["a"] = 100
}

Zeiger und Kanäle

Kanäle sind auch Referenztypen. Wenn Sie einen Kanal an eine Funktion übergeben, wird nur ein Zeiger kopiert.

go
func main() {
   ch := make(chan int)
   go send(ch)
   fmt.Println(<-ch) // 42
}

func send(ch chan<- int) {
   ch <- 42
}

Golang by www.golangdev.cn edit