使用場景:參數在語義上屬于不同組,Go 語法無法在單次調用中聲明多組可變參數,通過柯里化可以實現分步接收參數。
有的參數是在不同時間段產生,使用Currying可以讓函數記住(緩存)參數,避免應用代碼去手工管理緩存的參數。
demo代碼:
package mainimport "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})*/
}
測試:
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.123root@iZwz99zhkxxl5h6ecbm2xwZ:~/work/go#