Angesichts des folgenden Go-Codebeispiels:
package main import "fmt" type greeter interface { hello() goodbye() } type tourGuide struct { name string } func (t tourGuide) hello() { fmt.Println("Hello", t.name) } func (t *tourGuide) goodbye() { fmt.Println("Goodbye", t.name) } func main() { var t1 tourGuide = tourGuide{"James"} t1.hello() // Hello James t1.goodbye() // Goodbye James (same as (&t1).goodbye()) var t2 *tourGuide = &tourGuide{"Smith"} t2.hello() // Hello Smith t2.goodbye() // Goodbye Smith (same as (*t2).hello()) // illegal: t1 is not assignable to g1 (why?) // var g1 greeter = t1 var g2 greeter = t2 g2.hello() // Hello Smith g2.goodbye() // Goodbye Smith }
Im obigen Code können Sie Rufen Sie die beiden Methoden der Struktur tourGuide auf, indem Sie entweder eine Variable vom Typ tourGuide (t1) oder einen Zeiger auf tourGuide (t2) verwenden. Bei der Implementierung von Schnittstellen ändern sich jedoch die Dinge. Eine Variable vom Typ Greeter-Schnittstelle kann von einem Zeiger auf tourGuide zugewiesen werden, nicht jedoch von einem tourGuide-Wert. Warum ist das so?
Um den Grund zu verstehen, ist es wichtig, das Konzept der Empfängertypen und Wertesemantik zu verstehen. Methoden in Go können entweder einen Wertempfänger oder einen Zeigerempfänger haben. Eine Wertempfängermethode wird für eine Kopie des Werts aufgerufen, während eine Zeigerempfängermethode für den Originalwert aufgerufen wird.
Wenn ein Wert kopiert wird, wird eine neue unabhängige Kopie des Originalwerts erstellt. Etwaige an der Kopie vorgenommene Änderungen haben keinen Einfluss auf den ursprünglichen Wert. Dies wird als Wertesemantik bezeichnet.
Im tourGuide-Beispiel verfügt die hello-Methode über einen Wertempfänger und die goodbye-Methode über einen Zeigerempfänger. Wenn Sie t1.hello() aufrufen, wird eine Kopie von t1 erstellt und die Methode hello wird für die Kopie aufgerufen. Wenn Sie t1.goodbye() aufrufen, wird die Goodbye-Methode für den ursprünglichen t1-Wert aufgerufen.
Schnittstellen in Go werden durch Wertesemantik implementiert. Das heißt, wenn einer Schnittstelle ein Wert zugewiesen wird, wird eine Kopie des Werts erstellt. Im Fall einer Zeigerempfängermethode bedeutet dies, dass die Kopie des Werts keine Adresse hat und daher die Methode nicht darauf aufgerufen werden kann.
Zum Beispiel, wenn Sie t1 g1 zuweisen (was ist ein Schnittstellenwert) in der folgenden Codezeile:
// illegal: t1 is not assignable to g1 (why?) // var g1 greeter = t1
Eine Kopie von t1 wird erstellt und die Methoden „hello“ und „goodbye“ werden auf der Kopie implementiert. Da die Kopie jedoch keine Adresse hat, kann die Goodbye-Methode nicht darauf aufgerufen werden.
Im Gegensatz dazu, wenn Sie t2 zu g2 in der folgenden Codezeile zuweisen:
var g2 greeter = t2
Eine Kopie von t2 (das ein Zeiger auf tourGuide ist) wird erstellt und die Methoden „hello“ und „goodbye“ werden auf der Kopie des Zeigers implementiert. In diesem Fall hat die Kopie des Zeigers eine Adresse, sodass die Goodbye-Methode darauf aufgerufen werden kann.
Zusammenfassend der Grund, warum eine Variable vom Typ Greeter-Schnittstelle zuweisbar ist von einem Zeiger auf tourGuide, aber nicht von einem tourGuide-Wert, liegt daran, dass Schnittstellen durch Wertesemantik implementiert werden. Wenn einer Schnittstelle ein Wert zugewiesen wird, wird eine Kopie des Werts erstellt. Wenn die Methoden der Schnittstelle Zeigerempfänger haben, können sie nicht auf der Kopie aufgerufen werden, da die Kopie keine Adresse hat.
Das obige ist der detaillierte Inhalt vonWarum kann einer Go-„Greeter'-Schnittstelle kein „tourGuide'-Wert, aber ein Zeiger auf einen „tourGuide' zugewiesen werden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!