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# 
相关推荐
友友马30 分钟前
『QT』事件处理机制详解 (一)
开发语言·qt
孤独斗士43 分钟前
maven的pom文件总结
java·开发语言
confiself44 分钟前
通义灵码分析ms-swift框架中CHORD算法实现
开发语言·算法·swift
1024小神1 小时前
在 Swift 中,self. 的使用遵循明确的规则
开发语言·ios·swift
Swift社区1 小时前
Swift 类型系统升级:当协议遇上不可拷贝的类型
开发语言·ios·swift
chengpei1471 小时前
I²C协议简介
c语言·开发语言
唐古乌梁海1 小时前
【IT】常见计算机编程语言多继承问题
开发语言
雨中散步撒哈拉1 小时前
18、做中学 | 初升高 | 考场一 | 面向过程-家庭收支记账软件
开发语言·后端·golang
翔云 OCR API1 小时前
承兑汇票识别接口技术解析-开发者接口
开发语言·前端·数据库·人工智能·ocr
小白学大数据2 小时前
基于Splash的搜狗图片动态页面渲染爬取实战指南
开发语言·爬虫·python