I think the best way to explain this is by example, so here it is:
package main
import (
"fmt"
)
// Greeter greets with a Greeting.
type Greeter interface {
Greet() Greeting
}
// A Greeting has a string representation.
type Greeting interface {
String() string
}
type Hello struct {}
// Hello greets by returning itself...
func (h *Hello) Greet() *Hello {
return h
}
// ...because Hello also has a string representation.
func (h *Hello) String() string {
return "Hello"
}
// But Go says Hello doesn't implement Greeter.
func main() {
var g interface{} = &Hello{}
g, ok := g.(Greeter)
fmt.Println(ok)
}
This prints false
. You can run and play with it: https://play.golang.org/p/A_2k_ku_Q2
In my real case the struct Hello
and the interfaces for Greeter
and Greeting
are in different packages that do not import each other and I wanted to keep it that way. I'm perhaps missing some understanding of interfaces in Go but after reading so much about it I still can't put my finger on it. Would you guys have any pointers for me? Maybe another approach for the problem? Thanks!
As stated in the comments, problem here is once your interface has this signature:
type Greeter interface {
Greet() Greeting
}
The any valid implementation must use exactly Greeting
as the return type.
But, as the documentation shows, you don't need to give the interface a name:
https://golang.org/ref/spec#Interface_types
In order to be able to implement what you need, you might declare the interface directly in the return value, without giving it a name.
// Greeter greets with anything that has a String() method
type Greeter interface {
Greet() interface{ String() string }
}
Then your Greet()
function for Hello
can do this:
// Hello greets by returning itself...
func (h *Hello) Greet() interface{ String() string } {
return h
}
Find here a modified playground showing the working example:
https://play.golang.org/p/HteA_9jFd4
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With