假设我有代码,其中函数接受另一个作为参数:
type Person struct {
Name string
}
func personBuilder() * Person {
return &Person{Name: "John"}
}
func printRetrievedItem(callback func() interface {}){
fmt.Print(callback());
}
func doStuff(){
printRetrievedItem(personBuilder);
}
这会导致错误cannot use personBuilder (type func() *Person) as type func() interface {} in function argument
。如果我将personBuilder
返回类型更改为interface{}
,它可以正常工作,但在实际项目中我正在研究我希望有一个具体类型用于清晰设计和TDD目的。
Go支持这样的方法签名概括吗?有什么办法,如果你不能改变personBuilder
部分(例如,你有很多无参数函数返回不同类型的结构,并且你想构建一个接受任何构造函数作为参数的消费者函数)?
答案 0 :(得分:3)
要么像@GrzegorzŻur这样的包装器建议或定义您自己的界面并让xxxxBuilder
返回它:
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())
}
答案 1 :(得分:3)
您可以使用返回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);
}
这只是一个例子,请使用更好的名字!
要回答您的问题,fun() A
不是func() interface{}
,原因与[]A
不是[]interface{}
的原因相同。它在go wiki中得到了很好的解释。
答案 2 :(得分:1)
您可以使用pkg reflect
。 (但请注意,@OneOfOne的解决方案更具惯用性。)
package main
import (
"fmt"
"reflect"
)
type Person struct {
Name string
}
func personBuilder() *Person {
return &Person{Name: "John"}
}
func printRetrievedItem(callback interface{}) {
vals := reflect.ValueOf(callback).Call([]reflect.Value{})
fmt.Println(vals[0].Interface())
}
func main() {
printRetrievedItem(personBuilder) // &{John}
printRetrievedItem(func() string { return "hello" }) // hello
}
Here是操场上的一个例子。