Warum erzeugt „fmt.Println' von Go eine unerwartete Ausgabe mit eingebetteten Typen und mehreren „String()'-Methoden?

DDD
Freigeben: 2024-11-21 20:23:18
Original
986 Leute haben es durchsucht

Why Does Go's `fmt.Println` Produce Unexpected Output with Embedded Types and Multiple `String()` Methods?

Unerwartetes Verhalten der String()-Methode in eingebetteten Go-Typen

Bei der Verwendung eingebetteter Typen in Go gelten die Felder und Methoden des eingebetteten Typs effektiv vom umarmenden Typ vererbt. Dies kann zu unerwartetem Verhalten führen, insbesondere beim Umgang mit benutzerdefinierten String()-Methoden.

Betrachten Sie dieses Beispiel:

type Engineer struct {
    Person
    TaxPayer
    Specialization string
}

type Person struct {
    Name string
    Age  int
}

func (p Person) String() string {
    return fmt.Sprintf("name: %s, age: %d", p.Name, p.Age)
}

type TaxPayer struct {
    TaxBracket int
}

func (t TaxPayer) String() string {
    return fmt.Sprintf("%d", t.TaxBracket)
}
Nach dem Login kopieren

In diesem Code bettet der Typ „Ingenieur“ sowohl die Typen „Person“ als auch „TaxPayer“ ein , die eigene String()-Methoden zur Formatierung der jeweiligen Daten definieren. Wenn wir jedoch ein Engineer-Objekt instanziieren und fmt.Println(engineer) aufrufen, ist die Ausgabe nicht wie erwartet:

{name: John Doe, age: 35 3 Construction}
Nach dem Login kopieren

Diese Ausgabe deutet darauf hin, dass die Engineer.String()-Methode aufgerufen wird, aber die Die Methode TaxPayer.String() trägt ebenfalls zum Ergebnis bei. Dies liegt daran, dass die String()-Methode beim Einbetten zum Engineer-Typ hochgestuft wird und sowohl die Person.String()- als auch die TaxPayer.String()-Methode aufgerufen werden können.

Um dies zu verdeutlichen, beachten Sie Folgendes Szenario:

fmt.Println(engineer.String()) // Compile error: ambiguous selector engineer.String
Nach dem Login kopieren

In diesem Fall löst der Compiler einen Fehler aus, weil der Ingenieur über mehrere hochgestufte String()-Methoden verfügt, was zu einem mehrdeutigen Selektor führt. Allerdings ist fmt.Println(engineer) erfolgreich, weil der Compiler automatisch die Standardformatierung für Engineer basierend auf seinen Feldern auswählt.

Der Grund für diese offensichtliche Diskrepanz ist, dass die Funktion fmt.Println() im Wesentlichen die String-Konvertierung delegiert zum fmt-Paket. Wenn es auf einen Wert trifft, der die fmt.Stringer-Schnittstelle implementiert (die eine String()-Methode definiert), ruft es diese Methode auf, um die String-Darstellung zu erhalten.

In unserem Beispiel sind sowohl Person.String() als auch TaxPayer.String() ist vorhanden, keiner wird zum Engineer hochgestuft und die Standardformatierung wird verwendet. Im Fall von fmt.Println(engineer.String()) stößt der Compiler jedoch auf den mehrdeutigen Selektor und löst einen Fehler aus.

Zusammenfassend lässt sich sagen, dass eingebettete Typen zu unerwartetem Verhalten der String()-Methode führen können, wenn sie mehrere sind Eingebettete Typen definieren solche Methoden. Es ist wichtig, die Mechanismen der Einbettung und Methodenförderung zu verstehen, um mögliche Verwirrung zu vermeiden und die gewünschte Ausgabe sicherzustellen.

Das obige ist der detaillierte Inhalt vonWarum erzeugt „fmt.Println' von Go eine unerwartete Ausgabe mit eingebetteten Typen und mehreren „String()'-Methoden?. 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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage