When working with Go interfaces, an error can occur when an interface method that declares a return type of interface is implemented by a concrete type. This error arises because the implementation of the method does not directly return the interface type but instead returns a concrete type that implements the interface.
Consider the following example:
<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>
Here, the Printer function expects a StringerGetter interface, which has a GetStringer method that returns a fmt.Stringer, while the Bar type's GetStringer method returns a concrete type Foo that implements the fmt.Stringer interface. This causes the error:
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
The solution to this issue lies in making the methods of the interface match the expected interface types. In this case, the GetStringer method should return fmt.Stringer instead of a concrete type:
<code class="go">func (b *Bar) GetStringer() fmt.Stringer { return &Foo{"foo"} }</code>
Alternatively, one can create a wrapper type that implements the desired interface and delegates to the concrete type, as demonstrated in the following techniques:
Type Embedding with Delegation:
<code class="go">type MyBar struct{ Bar } func (b *MyBar) GetStringer() fmt.Stringer { return b.Bar.GetStringer() }</code>
Type Wrapping:
<code class="go">type MyBar Bar func (b *MyBar) GetStringer() fmt.Stringer { return &Foo{"foo"} }</code>
These techniques allow for seamless interfacing with concrete types without modifying them directly. By wrapping or embedding the concrete types, custom types can be created that adhere to the desired interface contracts.
The above is the detailed content of Why does Go throw an error when a concrete type implementation returns a concrete type instead of the expected interface type in an interface method?. For more information, please follow other related articles on the PHP Chinese website!