Maison > Article > développement back-end > Pourquoi Go génère-t-il une erreur lorsqu'une implémentation de type concret renvoie un type concret au lieu du type d'interface attendu dans une méthode d'interface ?
Lorsque vous travaillez avec des interfaces Go, une erreur peut se produire lorsqu'une méthode d'interface qui déclare un type de retour d'interface est implémentée par un type concret. Cette erreur survient car l'implémentation de la méthode ne renvoie pas directement le type d'interface mais renvoie plutôt un type concret qui implémente l'interface.
Considérons 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) }</code>
Ici, le La fonction Printer attend une interface StringerGetter, qui possède une méthode GetStringer qui renvoie un fmt.Stringer, tandis que la méthode GetStringer du type Bar renvoie un type concret Foo qui implémente l'interface fmt.Stringer. Cela provoque l'erreur :
prog.go:29: cannot use &f (type *Bar) as type StringerGetter in argument to Printer: *Bar does not implement StringerGetter (wrong type for GetStringer method) had GetStringer() *Foo want GetStringer() fmt.Stringer
La solution à ce problème réside dans le fait que les méthodes de l'interface correspondent aux types d'interface attendus. Dans ce cas, la méthode GetStringer doit renvoyer fmt.Stringer au lieu d'un type concret :
<code class="go">func (b *Bar) GetStringer() fmt.Stringer { return &Foo{"foo"} }</code>
Alternativement, on peut créer un type wrapper qui implémente l'interface souhaitée et délègue au type concret, comme démontré dans les techniques suivantes :
Incorporation de types avec délégation:
<code class="go">type MyBar struct{ Bar } func (b *MyBar) GetStringer() fmt.Stringer { return b.Bar.GetStringer() }</code>
Encapsulage de types:
<code class="go">type MyBar Bar func (b *MyBar) GetStringer() fmt.Stringer { return &Foo{"foo"} }</code>
Ces techniques permettre une interface transparente avec les types de béton sans les modifier directement. En encapsulant ou en intégrant les types concrets, des types personnalisés peuvent être créés qui respectent les contrats d'interface souhaités.
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!