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# 
相关推荐
白帽攻防录6 小时前
SRC 挖洞:PostScript 打印机驱动双 RCE,打印服务器怎么变成内网跳板
开发语言·网络安全·php·内网安全
十年Java程序媛6 小时前
Java枚举Enum完整教程|替代静态常量,开发与面试要点
java·开发语言·spring boot·后端·面试
2603_965148116 小时前
电商选品调研:通过关键词搜索API获取市场热销商品,结合商品详情API分析竞品卖点与定价
开发语言·数据库·人工智能·python·信息可视化
xixiaoyunya7 小时前
Python 异步编程入门:用 asyncio 轻松实现并发任务
开发语言·python·php
学逆向的7 小时前
C 循环结构的执行效率分析
c语言·开发语言·数据结构·网络安全
小坏讲微服务8 小时前
刚发布一个月的JDK 27,为什么我建议你立刻升级?
java·开发语言·spring boot·spring·架构·求职招聘·springboot4
打工仔折腾 AI9 小时前
用 Dashlet 把极空间 NAS 服务入口整理成统一导航首页的实践
java·开发语言·人工智能·后端·python·rpc·ai agent 实战
MATLAB代码顾问9 小时前
Simulink PI 参数扫描与批量仿真完整 MATLAB 代码
开发语言·matlab
Want59510 小时前
Python跳动的爱心②
开发语言·python·数学建模
小羊没烦恼!10 小时前
T-SQL查询进阶--理解SQL SERVER中的分区表
服务器·开发语言·前端·javascript·html