Den Unterschied zwischen t und *t verstehen
In diesem Codeausschnitt haben wir einen Typ TT mit einer String-Methode, die den fmt implementiert .Stringer-Schnittstelle:
package main import "fmt" type TT struct { a int b float32 c string } func (t *TT) String() string { return fmt.Sprintf("%+v", *t) } func main() { tt := &TT{3, 4, "5"} fmt.Printf(tt.String()) }
Dieser Code funktioniert, weil das fmt-Paket die String-Methode aufruft, um die String-Darstellung des TT-Werts abzurufen.
Allerdings, wenn die String-Methode geändert wird, um zu übernehmen ein Nicht-Zeiger-Empfänger:
func (t *TT) String() string { return fmt.Sprintf("%+v", t) }
er verursacht eine tote Schleife. Lassen Sie uns erklären, warum:
Der Aufruf von fmt.Sprintf("% v", t) übergibt einen *TT-Wert (Zeiger auf TT) an das fmt-Paket. Da die TT.String-Methode einen Zeigerempfänger hat, findet das FMT-Paket diese Methode nicht im Methodensatz des *TT-Typs.
Das Ändern des Empfängers in einen Nicht-Zeigertyp bedeutet, dass das FMT-Paket dies tut Finden Sie die String-Methode im Methodensatz von TT. Dies führt jedoch zu einer unendlichen Rekursion, da die aufgerufene Methode dieselbe ist, die zum Formatieren des Werts verwendet wird.
Um dieses Problem zu vermeiden, kann mit dem Schlüsselwort „type“ ein neuer Typ erstellt werden, der effektiv trennt Empfängertyp aus dem Wert, der an das fmt-Paket übergeben wird:
func (t TT) String() string { type TT2 TT return fmt.Sprintf("%+v", TT2(t)) }
Dies funktioniert, weil der neue Typ, der durch das Schlüsselwort „type“ erstellt wird, keine Methoden hat, sodass das fmt-Paket nicht versucht, den aufzurufen String-Methode für den neuen Typ.
Das obige ist der detaillierte Inhalt vonWarum führt das Ändern eines Methodenempfängers von Zeiger zu Nicht-Zeiger zu einer toten Schleife, wenn „fmt.Sprintf' verwendet wird?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!