Heim > Backend-Entwicklung > Golang > Warum ruft fmt.Println nicht die String-Methode meiner Stringer-Schnittstelle auf, wenn ein wertbasiertes Objekt übergeben wird?

Warum ruft fmt.Println nicht die String-Methode meiner Stringer-Schnittstelle auf, wenn ein wertbasiertes Objekt übergeben wird?

Susan Sarandon
Freigeben: 2024-12-06 19:35:15
Original
491 Leute haben es durchsucht

Why Doesn't fmt.Println Invoke My Stringer Interface's String Method When Passing a Value-Based Object?

Verwechslung der Stringer-Schnittstelle mit Println: Wertbasierte und zeigerbasierte Objekte verstehen

Frage:

Warum wird in einem Szenario, in dem ein Objekt die Stringer-Schnittstelle implementiert, die String-Methode des Objekts nicht abgerufen? Wird bei Verwendung von fmt.Println aufgerufen, wenn das Objekt wertbasiert ist?

Codebeispiel:

Betrachten Sie den folgenden Go-Code:

type Car struct {
    year int
    make string
}

func (c *Car) String() string {
    return fmt.Sprintf("{make:%s, year:%d}", c.make, c.year)
}

func main() {
    myCar := Car{year: 1996, make: "Toyota"}
    fmt.Println(myCar)
}
Nach dem Login kopieren

Wenn myCar ein Zeiger ist, wird die String-Methode wie erwartet aufgerufen. Wenn myCar jedoch ein Wert ist, wird stattdessen die standardmäßige Go-Formatierung verwendet.

Antwort:

Der Grund für dieses Verhalten liegt in der Funktionsweise der Go-Schnittstellen. Wenn Sie einen Typ angeben, der eine Schnittstelle implementiert (in diesem Fall Stringer), erwartet Go, dass dieser Typ genau der Typ der Schnittstelle ist. Wenn Sie einen Wert vom Typ Car an fmt.Println übergeben, wird er implizit in interface{} konvertiert, und im Typsystem interface{} gibt es keinen Typ Car. Stattdessen handelt es sich um einen Typ *Car (ein Zeiger auf Car).

Die Funktion fmt.Println verwendet einen Typschalter, um zu bestimmen, wie der Wert basierend auf seinem Typ gedruckt wird. Bei einer Stringer-Schnittstelle wird geprüft, ob der Wert die String-Methode implementiert. Da Car (wertbasiert) String nicht implementiert, wird die Standardformatierung verwendet. Wenn Sie myCar.String() jedoch explizit aufrufen, konvertiert der Compiler es automatisch in (&myCar).String(), das den richtigen *Car-Typ hat und die gewünschte Formatierungsmethode aufruft.

Um sicherzustellen, dass die Wenn das Objekt unabhängig von seinem Typ wie gewünscht formatiert wird, haben Sie zwei Möglichkeiten:

  1. Implement String on Car (value-based): Dies erfordert die Erstellung einer separaten String-Methode für Car, die mit Wertempfängern arbeitet, was unnötiges Kopieren von Objekten erfordern würde.
  2. Übergeben Sie immer einen Zeiger an fmt.Println: Durch die Verwendung von fmt.Println(&myCar ) stellen Sie sicher, dass der übergebene Wert den richtigen *Car-Typ hat und die String-Methode wie erwartet aufgerufen wird.

Das obige ist der detaillierte Inhalt vonWarum ruft fmt.Println nicht die String-Methode meiner Stringer-Schnittstelle auf, wenn ein wertbasiertes Objekt übergeben wird?. 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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage