使用场景:参数在语义上属于不同组,Go 语法无法在单次调用中声明多组可变参数,通过柯里化可以实现分步接收参数。
有的参数是在不同时间段产生,使用Currying可以让函数记住(缓存)参数,避免应用代码去手工管理缓存的参数。
demo代码:
go
package main
import "fmt"
// 2层柯里化函数:先接收arg,再接收otherArgs
func first(args ...int) func(args ...string) {
return func(otherArgs ...string) {
fmt.Println("Ints:", args)
fmt.Println("Strings:", otherArgs)
}
}
// 三层柯里化函数:先接收int,再接收string,最后接收bool
func tripleCurry(a ...int) func(b ...string) func(c ...bool) {
return func(b ...string) func(c ...bool) {
return func(c ...bool) {
fmt.Printf("Ints: %v\nStrings: %v\nBools: %v\n", a, b, c)
}
}
}
// 四层柯里化函数:先接收int,再接收string,然后bool,最后[]byte
func tripleCurry4(a ...int) func(b ...string) func(c ...bool) func(d ...[]byte) {
return func(b ...string) func(c ...bool) func(d ...[]byte) {
return func(c ...bool) func(d ...[]byte) {
return func(d ...[]byte) {
fmt.Printf("Ints: %v\nStrings: %v\nBools: %v\nBytes: %v\n", a, b, c, d)
}
}
}
}
// 五层柯里化函数:先接收int,再接收string,然后bool,然后[]byte,最后float64
func tripleCurry5(a ...int) func(b ...string) func(c ...bool) func(d ...[]byte) func(e float64) {
return func(b ...string) func(c ...bool) func(d ...[]byte) func(e float64) {
return func(c ...bool) func(d ...[]byte) func(e float64) {
return func(d ...[]byte) func(e float64) {
return func(e float64) {
fmt.Printf("Ints: %v\nStrings: %v\nBools: %v\nBytes: %v\n%v\n", a, b, c, d, e)
}
}
}
}
}
func main() {
fmt.Println("2层Currying")
first(100, 200)("a", "b")
fmt.Println()
fmt.Println("3层Currying")
tripleCurry(1, 2)("hello", "world")(true, false)
fmt.Println()
fmt.Println("4层Currying")
tripleCurry4(1, 2)("hello", "world")(true, false)([]byte{0x01, 0x02})
fmt.Println()
fmt.Println("5层Currying")
tripleCurry5(1, 2)("hello", "world")(true, false)([]byte{0x01, 0x02})(99.123)
fmt.Println()
// 分步调用示例
/*
step1 := tripleCurry4(10, 20)
step2 := step1("foo", "bar")
step3 := step2(true, false)
step3([]byte{0x03, 0x04})
*/
}
测试:
shell
root@iZwz99zhkxxl5h6ecbm2xwZ:~/work/go# go mod init tt
go: /root/work/go/go.mod already exists
root@iZwz99zhkxxl5h6ecbm2xwZ:~/work/go# go mod tidy
root@iZwz99zhkxxl5h6ecbm2xwZ:~/work/go#
root@iZwz99zhkxxl5h6ecbm2xwZ:~/work/go# ./tt
2层Currying
Ints: [100 200]
Strings: [a b]
3层Currying
Ints: [1 2]
Strings: [hello world]
Bools: [true false]
4层Currying
Ints: [1 2]
Strings: [hello world]
Bools: [true false]
Bytes: [[1 2]]
5层Currying
Ints: [1 2]
Strings: [hello world]
Bools: [true false]
Bytes: [[1 2]]
99.123
root@iZwz99zhkxxl5h6ecbm2xwZ:~/work/go#