2 回答
TA贡献1811条经验 获得超5个赞
首先,让我注意这与 的func() (interface{})含义相同func() interface{},因此我将使用较短的形式。
传递类型的函数 func() interface{}
func() interface{}只要传递给它的函数具有 type func() interface{},您就可以编写一个带有参数的泛型函数,如下所示:
type A struct {
Name string
Value int
}
type B struct {
Name1 string
Name2 string
Value float64
}
func doA() interface{} {
return &A{"Cats", 10}
}
func doB() interface{} {
return &B{"Cats", "Dogs", 10.0}
}
func Generic(w io.Writer, fn func() interface{}) {
result := fn()
json.NewEncoder(w).Encode(result)
}
您可以在实时操场上试用此代码:
http://play.golang.org/p/JJeww9zNhE
将函数作为类型参数传递 interface{}
如果要编写函数doA并doB返回具体类型的值,则可以将所选函数作为 type 参数传递interface{}。然后您可以使用该reflect包func() interface{}在运行时创建一个:
func Generic(w io.Writer, f interface{}) {
fnValue := reflect.ValueOf(f) // Make a concrete value.
arguments := []reflect.Value{} // Make an empty argument list.
fnResults := fnValue.Call(arguments) // Assume we have a function. Call it.
result := fnResults[0].Interface() // Get the first result as interface{}.
json.NewEncoder(w).Encode(result) // JSON-encode the result.
}
更简洁:
func Generic(w io.Writer, fn interface{}) {
result := reflect.ValueOf(fn).Call([]reflect.Value{})[0].Interface()
json.NewEncoder(w).Encode(result)
}
完整程序:
包主
import (
"encoding/json"
"io"
"os"
"reflect"
)
type A struct {
Name string
Value int
}
type B struct {
Name1 string
Name2 string
Value float64
}
func doA() *A {
return &A{"Cats", 10}
}
func doB() *B {
return &B{"Cats", "Dogs", 10.0}
}
func Generic(w io.Writer, fn interface{}) {
result := reflect.ValueOf(fn).Call([]reflect.Value{})[0].Interface()
json.NewEncoder(w).Encode(result)
}
func main() {
Generic(os.Stdout, doA)
Generic(os.Stdout, doB)
}
现场游乐场:
http://play.golang.org/p/9M5Gr2HDRN
TA贡献1871条经验 获得超13个赞
这些函数的返回签名是不同的: fn func() (interface {})vs.func doA() (A)和func doB() (B)
您收到编译器错误,因为您将具有不同签名的Generic函数传递到您的函数中。要解决此问题,您可以将函数更改为 return interface{}。
这是如何做到这一点的示例,我使用匿名结构并打印返回值而不是序列化它们,但这同样适用于您的示例:
package main
import "fmt"
func doA() interface{} {
return struct {
Name string
Value int
}{
"something",
5,
}
}
func doB() interface{} {
return struct {
Name1 string
Name2 string
Value float64
}{
"something",
"or other",
5.3,
}
}
func main() {
fmt.Println("Hello, playground", doA(), doB())
}
在 Go Playground 中对此进行实验:http : //play.golang.org/p/orrJw2XMW8
- 2 回答
- 0 关注
- 340 浏览
添加回答
举报