golang 柯里化(Currying)

使用场景:参数在语义上属于不同组,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# 
相关推荐
小羊没烦恼!1 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
伞伞悦读1 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
ttwuai1 天前
Go开源后台管理系统推荐:怎么按技术栈和边界比较4个官方仓库?
golang·gin
C语言小火车1 天前
C/C++ 为什么需要编译器?
开发语言·c++
codeejun1 天前
每日一Go·MySQL-5、锁机制全解析
云原生·golang
霍霍的袁1 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
孙启超1 天前
【AI开发之Rust】第 11 课:智能指针与内部可变性
开发语言·后端·rust
此生决int1 天前
深入理解C++系列(20)——C++11(下)
开发语言·c++
Achou.Wang1 天前
k8s中nginx worker process自动设置
后端·golang
CoderYanger1 天前
A.每日一题:835. 图像重叠
java·开发语言·程序人生·leetcode·面试·职场和发展·学习方法