Heim  >  Artikel  >  Backend-Entwicklung  >  Warum führt das Ändern eines Methodenempfängers von Zeiger zu Nicht-Zeiger zu einer toten Schleife, wenn „fmt.Sprintf“ verwendet wird?

Warum führt das Ändern eines Methodenempfängers von Zeiger zu Nicht-Zeiger zu einer toten Schleife, wenn „fmt.Sprintf“ verwendet wird?

DDD
DDDOriginal
2024-11-16 01:10:02148Durchsuche

Why Does Changing a Method Receiver from Pointer to Non-Pointer Lead to a Dead Loop When Using `fmt.Sprintf`?

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!

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