直接上代码
// 定义可柯里化函数形式
type function func(...interface{}) interface{}
// 通用柯里化函数
func (f function) curry(i interface{}) func(...interface{}) interface{} {
return func(values ...interface{}) interface{} {
values = append([]interface{}{i}, values...)
fmt.Println(values)
return f(values...)
}
}
首先定义一个类型,代表可柯里化函数,然后实现可柯里化函数的通用柯里化函数。
使用案例单元测试内容如下
// 等待实现柯里化的普通函数
func add(a, b int) int {
return a + b
}
func TestCurry(t *testing.T) {
// 把普通的函数转化成可柯里化函数
var addCurry function = func(values ...interface{}) interface{} {
return add(values[0].(int), values[1].(int))
}
// 调用柯里化过程生成新函数
add5 := addCurry.curry(5)
// 调用新函数产生最终结果
v := add5(8)
if v != 13 {
t.Error("期望13,实际", v)
}
}
说明
由于go语言强类型限制,我们没有办法把add函数直接传递给curry函数,必须通过特殊方式把一个普通函数转换成柯里化函数。转换过程不用思考,按下面方式处理。
// 这行是通用的,不用动
var addCurry function = func(values ...interface{}) interface{} {
// 在这里调用要转换的函数,把参数一个个转换成所需类型即可
return add(values[0].(int), values[1].(int))
}
继续讨论
由于go语言强类型限制,通用curry函数没能做到javascript那么方便,在使用时,多了一步普通函数转可柯里化函数的模板化代码,程序显得有些臃肿,降低了程序可读性,谁有更好的方案,欢迎拍砖。