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) }
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}
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
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!