Home  >  Article  >  Backend Development  >  Why Doesn\'t a Concrete Type Implementation Satisfy an Interface Method Returning an Interface in Go?

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

DDD
DDDOriginal
2024-10-26 22:48:03336browse

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

Interface Method Returning Interface Mismatch with Concrete Type Implementation

In Go, an interface method that returns an interface only matches an implementation that declares the interface itself, not 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) // compile-time error
}</code>

This code gives the following compile-time error:

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

To resolve this issue, either the GetStringer method in the Bar type should return a fmt.Stringer interface instead of a concrete *Foo type, or the StringerGetter interface should be modified to accept a concrete type instead of an interface.

Alternative Solutions

In cases where modifying the external concrete type or the shared interface is not desirable, there are two alternative solutions:

  1. Creating a Wrapper Type: You can create a new type that wraps the external concrete type and implements the desired interface. For example:
<code class="go">type MyBar struct {
    Bar
}

func (b *MyBar) GetStringer() fmt.Stringer {
    return b.Bar.GetStringer()
}</code>
  1. Embedding the Concrete Type: Alternatively, you can embed the external concrete type in your own type and implement the interface using the embedded type's methods. For example:
<code class="go">type MyBar struct {
    embed Bar
}

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

Both approaches allow you to work with the external concrete type while providing the desired interface implementation without modifying the original type or the shared interface.

The above is the detailed content of Why Doesn\'t a Concrete Type Implementation Satisfy an Interface Method Returning an Interface in Go?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
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