Maison  >  Article  >  développement back-end  >  Pourquoi une implémentation de type concret ne satisfait-elle pas à une méthode d'interface renvoyant une interface en Go ?

Pourquoi une implémentation de type concret ne satisfait-elle pas à une méthode d'interface renvoyant une interface en Go ?

DDD
DDDoriginal
2024-10-26 22:48:03336parcourir

Why Doesn't a Concrete Type Implementation Satisfy an Interface Method Returning an Interface in Go?

Méthode d'interface renvoyant une incompatibilité d'interface avec une implémentation de type concret

Dans Go, une méthode d'interface qui renvoie une interface ne correspond qu'à une implémentation qui déclare l'interface elle-même, pas une méthode concrète type qui implémente l’interface. Prenons l'exemple suivant :

<code class="go">package main

import "fmt"

type Foo struct {
    val string
}

func (f *Foo) String() string {
    return f.val
}

type StringerGetter interface {
    GetStringer() fmt.Stringer
}

type Bar struct{}

func (b *Bar) GetStringer() *Foo {
    return &Foo{"foo"}
}

func Printer(s StringerGetter) {
    fmt.Println(s.GetStringer())
}

func main() {
    f := Bar{}
    Printer(&f) // compile-time error
}</code>

Ce code donne l'erreur de compilation suivante :

cannot use &f (type *Bar) as type StringerGetter in argument to Printer:  *Bar does not implement StringerGetter (wrong type for GetStringer method)

Pour résoudre ce problème, soit la méthode GetStringer dans le type Bar doit renvoyer un fmt Interface .Stringer au lieu d'un type concret *Foo, ou l'interface StringerGetter doit être modifiée pour accepter un type concret au lieu d'une interface.

Solutions alternatives

Dans les cas où la modification du type concret externe ou l'interface partagée n'est pas souhaitable, il existe deux solutions alternatives :

  1. Création d'un type de wrapper : Vous pouvez créer un nouveau type qui enveloppe le type de béton externe et implémente le type souhaité interface. Par exemple :
<code class="go">type MyBar struct {
    Bar
}

func (b *MyBar) GetStringer() fmt.Stringer {
    return b.Bar.GetStringer()
}</code>
  1. Intégrer le type de béton : Alternativement, vous pouvez intégrer le type de béton externe dans votre propre type et implémenter l'interface à l'aide du type intégré méthodes. Par exemple :
<code class="go">type MyBar struct {
    embed Bar
}

func (b *MyBar) GetStringer() fmt.Stringer {
    return b.GetStringer()
}</code>

Les deux approches vous permettent de travailler avec le type concret externe tout en fournissant l'implémentation d'interface souhaitée sans modifier le type d'origine ou l'interface partagée.

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