«X does not implement Y»: Fehler mit pointer receiver in Go verstehen

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: Der Moment der Wahrheit für Go-Entwickler

\n\n

Wenn Sie jemals in Go (Golang) programmiert und Interfaces verwendet haben, sind Sie sicherlich auf diese Compiler-Meldung gestoßen:

\n\n
cannot use x (variable of type *MyStruct) as type MyInterface value in assignment:\n*MyStruct does not implement MyInterface (method GetName has a pointer receiver)
\n\n

Auf Stack Overflow erhält diese Frage tausende Aufrufe. Anfänger sind verwirrt, erfahrene zucken mit den Schultern. Aber hinter diesem Fehler steckt ein elegantes und wichtiges Konzept: der Unterschied zwischen value receiver und pointer receiver in der Sprache Go.

\n\n

In diesem Artikel werfen wir einen Blick «unter die Haube» des Go-Compilers, analysieren echte Codebeispiele und verstehen, wie man diese Falle vermeidet. Sie erfahren nicht nur warum der Fehler auftritt, sondern auch wie er mit dem Typ- und Interface-System zusammenhängt.

\n\n

1. Interfaces in Go: Kurze Einführung

\n\n

Bevor wir in den Fehler eintauchen, erinnern wir uns daran, wie Go-Interfaces funktionieren. Im Gegensatz zu Java oder C++ ist ein Interface in Go eine Menge von Methoden. Wenn ein Typ alle Methoden eines Interfaces implementiert, erfüllt er dieses Interface automatisch (Ententypisierung).

\n\n

Beispiel eines einfachen Interfaces:

\n\n
type Speaker interface {\n    Speak() string\n}
\n\n

Jetzt definieren wir eine Struktur und eine Methode:

\n\n
type Dog struct {\n    Name string\n}\n\n// Value receiver – die Methode arbeitet mit einer Kopie der Struktur\nfunc (d Dog) Speak() string {\n    return "Wuff! Ich bin " + d.Name\n}
\n\n

Hier implementiert Dog das Interface Speaker. Es funktioniert sowohl mit Dog als auch mit *Dog:

\n\n
var s Speaker\ns = Dog{Name: "Bello"}  // ✅ OK\ns = &Dog{Name: "Rex"}   // ✅ OK (Go dereferenziert automatisch)
\n\n

Bisher alles einfach. Ändern wir nun die Methode auf einen pointer receiver:

\n\n
func (d *Dog) Speak() string {\n    return "Wuff! Ich bin " + d.Name\n}
\n\n

Und hier beginnt die Magie.

\n\n

2. Pointer receiver vs Value receiver: Was ist der Unterschied?

\n\n

In Go können Methoden zwei Arten von Empfängern (receivers) haben:

\n\n
    \n
  • Value receiver (t Type) – die Methode erhält eine Kopie des Werts.
  • \n
  • Pointer receiver (t *Type) – die Methode erhält einen Zeiger auf den ursprünglichen Wert.
  • \n
\n\n

Warum ist das wichtig? Weil der Methodensatz eines Typs davon abhängt, welcher receiver verwendet wird.

\n\n

Wahrheitstabelle:

\n\n
    \n
  • Der Typ T hat alle Methoden mit value receiver (für T).
  • \n
  • Der Typ *T hat alle Methoden mit value receiver + pointer receiver.
  • \n
\n\n

Mit anderen Worten: Der Zeiger erhält einen «Bonus»-Methodensatz, während der Wert nur die Methoden hat, die mit value receiver deklariert sind.

\n\n

Das ist kein Bug, sondern ein Feature des Go-Designs. Der Compiler kann nicht automatisch die Adresse eines Werts nehmen, wenn dieser nicht adressierbar ist (z. B. das Ergebnis einer Funktion oder ein Literal).

\n\n

3. Analyse des Fehlers: «method has a pointer receiver»

\n\n

Kehren wir zu unserem Beispiel zurück. Wenn Speak() mit *Dog deklariert ist, dann:

\n\n
var s Speaker\ns = Dog{Name: "Bello"}  // ❌ FEHLER\n// cannot use Dog{...} as Speaker...\n// method has a pointer receiver
\n\n

Warum? Weil Dog (kein Zeiger) die Methode Speak() nicht in seinem Methodensatz hat. Die Methode gehört nur zu *Dog.

\n\n

Das hingegen funktioniert:

\n\n
s = &Dog{Name: "Bello"}  // ✅ OK
\n\n

Jetzt analysieren wir ein praxisnäheres Beispiel aus echtem Code, das oft auf Stack Overflow zu finden ist.

\n\n

Beispiel: Interface und Struktur mit Daten

\n\n
package main\n\nimport "fmt"\n\ntype User interface {\n    GetID() int\n    SetName(name string)\n}\n\ntype Admin struct {\n    ID   int\                

Blogs

Buchempfehlungen