Heim > Backend-Entwicklung > Golang > Warum führt die Verwendung von „t' vs. „*t' als Empfänger in „fmt.Stringer' von Go zu einer toten Schleife?

Warum führt die Verwendung von „t' vs. „*t' als Empfänger in „fmt.Stringer' von Go zu einer toten Schleife?

Patricia Arquette
Freigeben: 2024-11-22 22:49:12
Original
773 Leute haben es durchsucht

Why does using `t` vs `*t` as a receiver in Go's `fmt.Stringer` lead to a dead loop?

Den Unterschied zwischen t und *t verstehen: Eine Fallstudie aus dem fmt-Paket

In Go bietet das fmt-Paket leistungsstarke Formatierungsfunktionen , sodass Entwickler die Art und Weise, wie Werte gedruckt werden, anpassen können. Allerdings kann ein subtiler Unterschied zwischen t und *t zu unerwartetem Verhalten führen, nämlich zu einer toten Schleife, wenn es innerhalb einer Empfängermethode verwendet wird.

Beachten Sie den folgenden Codeausschnitt:

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())
}
Nach dem Login kopieren

Dieser Code wird erfolgreich ausgeführt und gibt den Inhalt der Variablen „tt“ als „tt={a:3, b:4, c:5}“ aus. Wenn wir jedoch die String-Methode wie folgt ändern:

func (t *TT) String() string {
    return fmt.Sprintf("%+v", t)
}
Nach dem Login kopieren

Dies führt zu einer toten Schleife. Der Grund liegt in der Art und Weise, wie das fmt-Paket Werte verarbeitet, die die String()-Methode implementieren (implementiert die fmt.Stringer-Schnittstelle).

Wenn der Wert von 'tt' an fmt.Println übergeben wird, wird das fmt-Paket prüft, ob der Typ TT die String()-Methode implementiert. Da wir die String()-Methode mit einem Zeigerempfänger (*TT) definiert haben, enthält die für TT festgelegte Methode String() nicht. Folglich ruft das fmt-Paket tt.String() nicht auf.

Andererseits definieren wir im modifizierten Code-Snippet die String()-Methode mit einem Empfängertyp *TT. In diesem Fall umfasst die für TT festgelegte Methode String(). Da wir jedoch tt übergeben, das vom Typ *TT ist, ruft der Aufruf von tt.String() im Wesentlichen die String()-Methode rekursiv auf, was zu einer Endlosschleife führt.

Um dieses Problem zu verhindern, ist es ratsam, dies zu tun Verwenden Sie einen anderen Empfängertyp für die String()-Methode. Ein Ansatz besteht darin, mit dem Schlüsselwort „type“ einen neuen Typ zu erstellen und eine Typkonvertierung für den übergebenen Wert durchzuführen. Dadurch wird ein neuer Typ ohne Methoden erstellt und die Endlosschleife vermieden.

Zum Beispiel:

func (t TT) String() string {
    type TT2 TT
    return fmt.Sprintf("%+v", TT2(t))
}
Nach dem Login kopieren

In diesem Fall stellt die Konvertierung von t in TT2 effektiv sicher, dass die String()-Methode dies nicht tut rekursiv aufgerufen werden, da TT2 keine String()-Methode hat.

Das Verständnis der Unterscheidung zwischen t und *t im Kontext des fmt-Pakets ist von entscheidender Bedeutung um unerwartetes Verhalten zu vermeiden und eine effiziente Codeausführung sicherzustellen.

Das obige ist der detaillierte Inhalt vonWarum führt die Verwendung von „t' vs. „*t' als Empfänger in „fmt.Stringer' von Go zu einer toten Schleife?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage