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# 
相关推荐
专注VB编程开发20年32 分钟前
各版本操作系统对.NET支持情况(250707更新)
开发语言·前端·ide·vscode·.net
我喜欢就喜欢40 分钟前
RapidFuzz-CPP:高效字符串相似度计算的C++利器
开发语言·c++
莫彩43 分钟前
【Modern C++ Part7】_创建对象时使用()和{}的区别
开发语言·c++
星光54221 小时前
飞算JavaAI:给Java开发装上“智能引擎”的超级助手
java·开发语言
June bug1 小时前
【Python基础】变量、运算与内存管理全解析
开发语言·python·职场和发展·测试
醇醛酸醚酮酯1 小时前
Qt项目锻炼——TODO(五)
开发语言·qt
蹦蹦跳跳真可爱5892 小时前
Python----OpenCV(几何变换--图像平移、图像旋转、放射变换、图像缩放、透视变换)
开发语言·人工智能·python·opencv·计算机视觉
骁的小小站2 小时前
HDLBits刷题笔记和一些拓展知识(十一)
开发语言·经验分享·笔记·其他·fpga开发
Jtti2 小时前
如何准确查看服务器网络的利用率?
开发语言·php
人生在勤,不索何获-白大侠2 小时前
day17——Java集合进阶(Collections、Map)
java·开发语言