假设我有代码,其中一个函数接受另一个作为参数:
type Person struct {
Name string
}
func personBuilder() * Person {
return &Person{Name: "John"}
}
func printRetrievedItem(callback func() interface {}){
fmt.Print(callback());
}
func doStuff(){
printRetrievedItem(personBuilder);
}
Run Code Online (Sandbox Code Playgroud)
这导致错误cannot use personBuilder (type func() *Person) as type func() interface {} in function argument。如果我将personBuilder返回类型更改为interface{},它可以工作,但在我正在处理的实际项目中,我希望有一个具体的类型来实现清晰的设计和 TDD 目的。
Go 是否支持这种方法签名泛化?如果您无法更改personBuilder部件(例如,您有很多返回不同类型结构的无参数函数,并且您想构建一个接受这些构建器中的任何一个作为参数的消费者函数),有什么解决方法?
您可以为此使用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
}
Run Code Online (Sandbox Code Playgroud)
这是操场上的一个例子。