Heim  >  Artikel  >  Backend-Entwicklung  >  Welche Auswirkungen hat die Verwendung von „*t“ vs. „t“ als Methodenempfänger in Go und wie können tote Schleifen bei Verwendung von „fmt.String()“ verhindert werden?

Welche Auswirkungen hat die Verwendung von „*t“ vs. „t“ als Methodenempfänger in Go und wie können tote Schleifen bei Verwendung von „fmt.String()“ verhindert werden?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-17 10:53:02844Durchsuche

What are the implications of using `*t` vs. `t` as method receivers in Go, and how can dead loops be prevented when using `fmt.String()`?

Die Nuancen von *t vs. t im Methodenaufruf von Go verstehen

In Go ist die Verwendung von Zeigern ('*') in Methodenempfänger können erhebliche Auswirkungen auf die Funktionsweise der Methode haben. Dieser Unterschied wird im folgenden Codeausschnitt hervorgehoben:

package main

import "fmt"

type TT struct {
    a int
    b float32
    c string
}

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

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

func main() {
    tt := &TT{3, 4, "5"}
    fmt.Printf(tt.String())
}

Die ursprüngliche Implementierung der String()-Methode verwendet einen Zeigerempfänger (*TT), wodurch die Gefahr des Zugriffs auf einen Nullzeiger vermieden wird, wenn t Null ist . Das Ändern der String()-Methode zur Verwendung eines Nicht-Zeiger-Empfängers (TT) führt jedoch zu einer Dead-Loop.

Grund für Dead-Loop:

Der Schlüssel zu Das Verständnis dieses Verhaltens hängt davon ab, wie das fmt-Paket von Go mit Typen umgeht, die die fmt.Stringer-Schnittstelle implementieren (d. h. Typen, die eine benutzerdefinierte String()-Methode bereitstellen). Beim Drucken eines Werts vom Typ *TT prüft fmt.String() zunächst, ob *TT eine gültige String()-Methode implementiert. Wenn dies der Fall ist, wird diese Methode aufgerufen, um die Zeichenfolgendarstellung des Werts zu erhalten. Dies funktioniert gut, wenn *TT einen Zeigerempfänger hat, da der Methodensatz von *TT die String()-Methode enthält.

Wenn jedoch der Empfänger von String() in einen Nicht-Zeigertyp geändert wird (d. h. TT) tritt das Problem auf. In diesem Fall enthält der Methodensatz von TT die Methode String(), was bedeutet, dass fmt.String(), wenn er versucht, den Wert von t (einer Instanz von TT) auszugeben, t.String() aufruft, was in turn ruft sich erneut auf, was zu einer unendlichen Rekursion führt.

Verhindern der Dead Loop:

Um die Dead Loop zu verhindern, kann man eine Technik namens Typkonvertierung anwenden. Durch das Erstellen eines neuen Typs mithilfe des Schlüsselworts type und das Konvertieren des an fmt.String() übergebenen Werts kann die unendliche Rekursion vermieden werden:

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

In diesem Fall verfügt der neue Typ (TT2) über keine Methoden Wenn also fmt.String() versucht, den konvertierten Wert auszugeben, wird keine String()-Methode für den konvertierten Typ aufgerufen.

Schlussfolgerung:

Verstehen Der Unterschied zwischen *t und t in Methodenempfängern ist entscheidend, um mögliche Fallstricke beim Drucken benutzerdefinierter Typen mit der Funktion fmt.String() zu vermeiden. Indem man den Empfängertyp sorgfältig berücksichtigt und bei Bedarf eine Typkonvertierung einsetzt, kann man tote Schleifen verhindern und das korrekte Funktionieren von Methodenaufrufen sicherstellen.

Das obige ist der detaillierte Inhalt vonWelche Auswirkungen hat die Verwendung von „*t“ vs. „t“ als Methodenempfänger in Go und wie können tote Schleifen bei Verwendung von „fmt.String()“ verhindert werden?. 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