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# 
相关推荐
胖咕噜的稞达鸭3 分钟前
C++篇 String实现避坑指南:搞定构造,拷贝与析构,增删查改,流提取流插入与比对大小 一文全解
开发语言·数据结构·c++
歪歪10017 分钟前
如何根据实际需求选择使用 TCP 或 UDP 协议?
开发语言·网络·网络协议·tcp/ip·计算机网络·udp
不枯石25 分钟前
Matlab通过GUI实现点云的导向(引导)滤波(附最简版)
开发语言·图像处理·算法·计算机视觉·matlab
熊猫_豆豆27 分钟前
MATLAB 九大行星太阳系运行程序
开发语言·nginx·matlab
枣伊吕波1 小时前
五十三、bean的管理-bean的获取、bean的作用域、第三方bean
java·开发语言
丁浩6661 小时前
Python---14.Python数据存储EXCEl和MySQL
开发语言·python
Tisfy1 小时前
MacOS - Clang使用bits/stdc++.h - 非官方(竞赛用) - 通用方法
开发语言·c++·macos
啦工作呢1 小时前
Sass:CSS 预处理器
开发语言·后端·rust
豆豆·丁1 小时前
kettle 执行java脚本生成SQL
java·开发语言·数据库
吹晚风吧1 小时前
线程安全之《Sychronized的八锁案例》
java·开发语言··sychronized