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?

DDD
Release: 2024-10-30 07:33:02
Original
187 people have browsed it

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?

Interface Method Returning Interface Mismatch with Concrete Type Implementation

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>
Copy after login

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
Copy after login

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>
Copy after login

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>
Copy after login

Type Wrapping:

<code class="go">type MyBar Bar

func (b *MyBar) GetStringer() fmt.Stringer {
    return &Foo{"foo"}
}</code>
Copy after login

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!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!