描述任何 go 函数的类型

我想编写一个将函数部分应用于参数的函数,如下所示:


func partial(f AnyFuncType, arg interface{}) AnyFuncType {

   return func(args ...interface{}) interface{} { 

       return f(arg, args)

   }

}


type AnyFuncType func(args ...interface{}) interface{}

但是即使使用像这样最简单的功能也不起作用


func sum(a int, b int) int {

  return a + b


func main() {

  addToFive := partial(sum, 5)

}

因为我得到


./prog.go:16:23: cannot use sum (type func(int, int) int) as type AnyFuncType in argument to partial

编译错误。现在,我知道我可以使用 interface{},但是有没有办法为 f 指定一个更精确的类型,它可以与任何函数一起使用?


慕妹3146593
浏览 109回答 3
3回答

米琪卡哇伊

您试图将interface{}其视为泛型类型,但interface{}不是泛型类型,并且 go 将不匹配interface{}作为采用具体类型的函数的签名的函数的签名。

回首忆惘然

用于interface{}表示任何类型的函数。没有更精确的类型适用于任何功能。使用反射包来实现partial。func partial(f interface{}, arg interface{}) interface{} {&nbsp; &nbsp; v := reflect.ValueOf(f)&nbsp; &nbsp; t := v.Type()&nbsp; &nbsp; var in []reflect.Type&nbsp; &nbsp; for i := 1; i < t.NumIn(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; in = append(in, t.In(i))&nbsp; &nbsp; }&nbsp; &nbsp; var out []reflect.Type&nbsp; &nbsp; for i := 0; i < t.NumOut(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; out = append(out, t.Out(i))&nbsp; &nbsp; }&nbsp; &nbsp; var va reflect.Value&nbsp; &nbsp; if arg != nil {&nbsp; &nbsp; &nbsp; &nbsp; va = reflect.ValueOf(arg)&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; // Support `nil` as partial argument.&nbsp; &nbsp; &nbsp; &nbsp; va = reflect.Zero(t.In(0))&nbsp; &nbsp; }&nbsp; &nbsp; return reflect.MakeFunc(reflect.FuncOf(in, out, t.IsVariadic()),&nbsp; &nbsp; &nbsp; &nbsp; func(args []reflect.Value) []reflect.Value {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return v.Call(append([]reflect.Value{va}, args...))&nbsp; &nbsp; &nbsp; &nbsp; }).Interface()}像这样使用它:addToFive := partial(sum, 5).(func(int) int)fmt.Println(addToFive(1))在操场上运行它。我建议使用闭包来创建部分而不是partial这个答案中的函数。闭包更有效,避免了棘手的反射代码。addToFive := func(x int) int { return sum(5, x) }fmt.Println(addToFive(1))

12345678_0001

问题是,GO 中的子类型仅适用于交互。由于 AnyFuncType 不是接口,因此这不起作用。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go