Suppose I have code, where a function accepts another one as an argument:
type Person struct {
Name string
}
func personBuilder() * Person {
return &Person{Name: "John"}
}
func printRetrievedItem(callback func() interface {}){
fmt.Print(callback());
}
func doStuff(){
printRetrievedItem(personBuilder);
}
This results in error cannot use personBuilder (type func() *Person) as type func() interface {} in function argument. If I change personBuilder return type to interface{}, it works, but in real project I'm working on I want to have a concrete type for clear design and TDD purposes.
Does Go support such method signature generalization? What are the workarounds, if you could not change the personBuilder part (e.g. you have a lot parameterless functions that return different type of struct, and you want to build a consumer function that accepts any of those builders as argument)?
One workaround is to define an inline function that calls personBuilder.
printRetrievedItem(func() interface{} {return personBuilder()});
Playground
You can create an interface with a method that returns an interface{}:
type Thinger interface {
Thing() interface{}
}
func (p *Person) Thing() interface{} {
return p
}
func printRetrievedItem(t Thinger){
fmt.Print(t.Thing());
}
func doStuff(){
printRetrievedItem(personBuilder);
}
This is just an example, please use a better name!
To answer your question, fun() A is not a func() interface{}, for the same reason that []A is not an []interface{}. It's explained very well in the go wiki.
Either do a wrapper like @GrzegorzŻur suggested or define your own interface and make your xxxxBuilder return it:
type Namer interface {
Name() string
}
type Person struct {
name string
}
func (p *Person) Name() string {
return p.name
}
func personBuilder() Namer {
return &Person{name: "John"}
}
func printRetrievedItem(callback func() Namer) {
fmt.Printf("%T: %v", callback(), callback().Name())
}
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