Heim >Backend-Entwicklung >Golang >Warum führt ein Zeigerempfänger in der String-Methode zu einer toten Schleife in Go?

Warum führt ein Zeigerempfänger in der String-Methode zu einer toten Schleife in Go?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-23 21:15:20818Durchsuche

Why Does a Pointer Receiver in String Method Lead to a Dead Loop in Go?

Zeigerempfänger vs. Wertempfänger in der String-Methode

In Go wird die String()-Methode verwendet, um die String-Darstellung eines Benutzers zu steuern Typ. Bei der Definition der String()-Methode ist es wichtig, den Unterschied zwischen einem Zeigerempfänger und einem Wertempfänger zu verstehen.

Bedenken Sie den folgenden Code:

type TT struct {
    a int
    b float32
    c string
}

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

In diesem Code ist der String( )-Methode verfügt über einen Zeigerempfänger, was bedeutet, dass sie mit einem Zeiger auf einen TT-Wert arbeitet. Der Aufruf von tt.String() ruft effektiv (*tt).String() auf.

Erwägen Sie nun, die String()-Methode wie folgt zu ändern:

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

Diese Änderung entfernt den Zeiger Empfänger, wodurch die String()-Methode mit einem Wert vom Typ TT arbeitet.

Warum führt dies zu einem toten Wert? Schleife?

Das fmt-Paket prüft, ob der auszugebende Wert die Stringer-Schnittstelle implementiert (oder über eine String()-Methode verfügt). Wenn ja, wird diese Methode aufgerufen, um die Zeichenfolgendarstellung zu erhalten. In diesem Fall haben wir jedoch einen Zeigerempfänger für die String()-Methode.

Wenn wir tt.String() aufrufen, übergibt das fmt-Paket einen Wert vom Typ *TT. Allerdings erwartet die String()-Methode einen Wert vom Typ TT. Diese Nichtübereinstimmung führt dazu, dass das fmt-Paket die String()-Methode erneut aufruft, die wiederum erneut aufgerufen wird, und so weiter, was zu einer Endlosschleife führt.

Prävention/Schutz

Um diese tote Schleife zu verhindern, stellen Sie sicher, dass der Empfängertyp der String()-Methode mit dem Typ des an das fmt-Paket übergebenen Werts übereinstimmt. Wenn Sie aus irgendeinem Grund denselben Empfängertyp verwenden müssen, können Sie mit dem Schlüsselwort type einen neuen Typ erstellen und den Wert in den neuen Typ konvertieren, bevor Sie fmt.Sprintf aufrufen:

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

Indem Sie einen neuen Typ erstellen Typ entfernen wir alle Methoden aus dem zugrunde liegenden Typ, wodurch der Kreislauf effektiv durchbrochen wird und wir fmt.Sprintf.

sicher aufrufen können

Das obige ist der detaillierte Inhalt vonWarum führt ein Zeigerempfänger in der String-Methode zu einer toten Schleife in Go?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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