Direkt zum Hauptinhalt springen
eLearner.app
Modul 5 · Lektion 2 von 522/50 im Kurs~14 min
Lektionen des Moduls (2/5)

Methoden: Wert- vs. Zeiger-Receiver

Eine Methode in Go ist eine Funktion mit einem Empfänger: einem Special zwischen func und dem Methodennamen deklarierter Parameter, der die bindet Methode zu einem Typ. Es gibt keine Klassen: Methoden können definiert werden Jeder benannte Typ, der im aktuellen Paket deklariert ist.

Syntax

Go
type Person struct {
    Name string
}

func (p Person) Greet() string {
    return "ciao " + p.Name
}

p := Person{Name: "Ada"}
fmt.Println(p.Greet())   // "ciao Ada"

Der Empfänger p Person macht Greet zu einer Methode von Person. Im Inneren Methode ist p eine Variable wie jede andere.

Wertempfänger vs. Zeigerempfänger

Go
// VALUE receiver: operates on a COPY of the value
func (p Person) NameUpper() string {
    return strings.ToUpper(p.Name)
}

// POINTER receiver: operates on the original value, can mutate it
func (p *Person) Rename(n string) {
    p.Name = n
}

Mit einem Zeigerempfänger können Sie den Empfänger modifizieren und die Änderungen vornehmen sind außerhalb der Methode sichtbar. Mit einem Wertempfänger können Sie das nicht – Sie würden es tun Ändern Sie nur die lokale Kopie.

Go
p := Person{Name: "Ada"}
p.Rename("Grace")
fmt.Println(p.Name)   // "Grace" — change is visible

Wann sollte ein Zeigerempfänger verwendet werden?

Praktische Regeln, in der Reihenfolge ihrer Priorität:

  1. Sie müssen den Empfänger ändern → Zeigerempfänger. Obligatorisch.
  2. Die Struktur ist groß (Dutzende Felder, Arrays darin) → Zeiger Empfänger, um teure Kopien zu vermeiden.
  3. Konsistenz: Wenn MINDESTENS eine Methode für den Typ einen Zeigerempfänger hat, verwenden Sie ein Zeigerempfänger auch für die anderen. Eine sehr wichtige Tagung für Schnittstellen (Modul 6).
  4. Kleine, unveränderliche „Wert“-Typen (Zeit. Zeit, komplexe Zahlen, klein Strukturen) → Wertempfänger, besser lesbar.

Methoden für Nicht-Strukturtypen

Sie können Methoden für jeden in Ihrem Paket deklarierten NAMED-Typ definieren:

Go
type Celsius float64

func (c Celsius) ToFahrenheit() float64 {
    return float64(c)*9/5 + 32
}

t := Celsius(20)
fmt.Println(t.ToFahrenheit())  // 68

Sie können sie nicht für Typen aus anderen Paketen (z. B. int, string) definieren: Sie müssen Erstellen Sie zunächst einen lokalen benannten Typ.

Probieren Sie es aus

Übung#go.m5.l2.e1
Versuche: 0Wird geladen…

Fügen Sie eine Greet()-String-Methode (Wertempfänger) zu Person hinzu, die „ciao <Name>“ zurückgibt.

Editor wird geladen…
Hinweis anzeigen

Empfänger in Klammern VOR dem Methodennamen.

Lösung nach 3 Versuchen verfügbar

Übung#go.m5.l2.e2
Versuche: 0Wird geladen…

Fügen Sie eine Rename(n string)-Methode mit einem POINTER-Empfänger hinzu, der p.Name ändert.

Editor wird geladen…
Hinweis anzeigen

Zeigerempfänger: `(p *Person)`.

Lösung nach 3 Versuchen verfügbar

Quiz#go.m5.l2.e3
Bereit

Wann sollten Sie einen Zeigerempfänger (p *T) verwenden?

Go
func (t ?T) M() { ... }
Antwortoptionen

Zusammenfassung

  • Methode = Funktion mit einem Empfänger: func (r T) Name(...) ... { ... }.
  • Wertempfänger: bearbeitet eine Kopie; Zeigerempfänger: arbeitet auf dem Original.
  • Go führt die T*T-Konvertierung automatisch am Anrufort durch.
  • Zeigerempfänger, wenn: Mutation + große Struktur + Konsistenz mit anderen Methoden des Typs.
  • Mischen Sie niemals Wert- und Zeigerempfänger desselben Typs. – Methoden gelten für NAMED-Typen im aktuellen Paket (einschließlich Nicht-Strukturen).