Maison  >  Article  >  développement back-end  >  Pourquoi « fmt.Println » de Go produit-il une sortie inattendue lors de l'intégration de types avec des méthodes « String() » contradictoires ?

Pourquoi « fmt.Println » de Go produit-il une sortie inattendue lors de l'intégration de types avec des méthodes « String() » contradictoires ?

Patricia Arquette
Patricia Arquetteoriginal
2024-11-24 09:08:10292parcourir

Why Does Go's `fmt.Println` Produce Unexpected Output When Embedding Types with Conflicting `String()` Methods?

Comportement inattendu de la méthode String() avec les types intégrés

Dans Go, l'intégration permet aux types d'inclure des champs et des méthodes d'un autre type dans leur propre structure. Cependant, lorsque plusieurs types incorporés définissent une méthode portant le même nom (comme String()), certains scénarios peuvent conduire à un comportement inattendu.

Considérez le code suivant :

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

func main() {
    engineer := Engineer{
        Person: Person{
            Name: "John Doe",
            Age:  35,
        },
        TaxPayer: TaxPayer{3},
        Specialization: "Construction",
    }
    fmt.Println(engineer)
}

Quand ce code est exécuté, il produit le résultat suivant :

{name: John Doe, age: 35 3 Construction}

Ce résultat peut sembler déroutant, car il existe plusieurs méthodes String() définies dans les types intégrés Person et TaxPayer. Cependant, l'ambiguïté est résolue par les règles suivantes :

  • Si plusieurs types intégrés définissent une méthode String(), elle est considérée comme un « sélecteur illégal », ce qui signifie qu'elle n'est pas accessible directement (en appelant l'ingénieur .String(), par exemple).
  • Par conséquent, aucune méthode String() n'est promue au type d'intégration (Engineer), et donc le formatage par défaut (impression des valeurs des champs) est utilisé.
  • Cependant, lorsque le package fmt tente de produire une représentation sous forme de chaîne par défaut pour la valeur Engineer, il vérifie si la valeur implémente l'interface fmt.Stringer (qui a une méthode String()).
  • Puisque le type Person implémente fmt.Stringer, sa méthode String() est appelée pour produire la représentation sous forme de chaîne des champs (nom et age).

La suppression de la méthode Person.String() ou de la méthode TaxPayer.String() résout l'ambiguïté, permettant à la méthode String() restante d'être utilisée pour le formatage par défaut.

Le point clé à retenir de ce comportement est que les types intégrés promeuvent leurs méthodes String() uniquement si une méthode unique et sans ambiguïté est définie. Si plusieurs méthodes existent, le type d'intégration n'a pas de méthode String() promue et le formatage par défaut est utilisé.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn