• golang 函数式编程库samber/mo使用: IO


    golang 函数式编程库samber/mo使用: IO

    如果您不了解samber/mo库, 请先阅读第一篇 Option

    在函数式编程中,副作用和纯函数是最常见的概念。 IO用来封装IO这类副作用。

    什么是副作用

    副作用是在计算结果的过程中,改变了系统状态或者与外部世界进行了可观察的交互。副作用包括但不限于:

    • 操作文件系统
    • 往数据库插入记录
    • 调用http请求
    • 修改全局变量
    • 打印日志
    • 访问系统状态

    副作用之所以不好,是因为它使得代码难以理解和测试。当系统状态或者外界环境发生变化时, 同一段代码的执行会产生不同的结果。如下所示:

    var globalVar int
    
    func incrementGlobalVar() {
        globalVar++
    }
    
    func main() {
        fmt.Println("Before:", globalVar)
        incrementGlobalVar()
        fmt.Println("After:", globalVar)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    什么是纯函数

    纯函数是指一个函数,给定相同的输入,总是返回相同的输出,并且没有任何可观察的副作用。不取决于系统状态,也不会对系统状态进行修改。 这类函数具有参数透明性、可测试性、并行性等诸多优秀特性, 所以我们偏好纯函数。但是只有纯函数也是不可能的, 我们必然会和外界进行交互, 所以只能尽可能得进行隔离。mo.IO就是用来包装IO操作的。

    IO的使用

    我们通过一个例子说明IO的使用, 我们写一个判断是否周末的函数, 这需要依赖系统时间。我们可以用mo.NewIO将这个依赖封装起来, 用 Run函数正式执行获取今天是周几。

    package main
    
    import (
    	"time"
    
    	"github.com/samber/mo"
    )
    
    func checkIfTodayWeekend(today mo.IO[int]) bool {
    	result := today.Run()
    	return result%6 == 0 || result%7 == 0
    }
    
    func main() {
    	today := mo.NewIO(func() int {
    		return int(time.Now().Weekday())
    	})
    	println("today is %v", today.Run())
    	println("today is weekend? %v", checkIfTodayWeekend(today))
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    由于我们隔离了系统依赖, 测试变得非常简单

    package main
    
    import (
    	"testing"
    
    	"github.com/samber/mo"
    )
    
    func TestCheckIfTodayWeekend(t *testing.T) {
    	// Mock the current day of the week as Tuesday (2)
    	today := mo.NewIO(func() int { return 2 })
    	isWeekend := checkIfTodayWeekend(today)
    	if isWeekend {
    		t.Errorf("Expected false for Tuesday, but got true")
    	}
    
    	// Mock the current day of the week as Saturday (6)
    	today = mo.NewIO(func() int { return 6 })
    	isWeekend = checkIfTodayWeekend(today)
    	if !isWeekend {
    		t.Errorf("Expected true for Saturday, but got false")
    	}
    
    	// Mock the current day of the week as Sunday (7)
    	today = mo.NewIO(func() int { return 7 })
    	isWeekend = checkIfTodayWeekend(today)
    	if !isWeekend {
    		t.Errorf("Expected true for Sunday, but got false")
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
  • 相关阅读:
    ubuntu(20.04)下截图贴图软件——flameshot(带设快捷键)
    Web3.0时代的身份与信任
    C++的编译链接与在vs中build提速
    Flask四种配置方式
    Chrome(谷歌浏览器)安装Vue插件vue-devtools(最新版+图文详解附带免费下载地址)
    Go微服务框架go-kratos实战05:分布式链路追踪 OpenTelemetry 使用
    质量问题不是不爆,时候未到
    基于VGG与LSTM实现针对图片的问答任务 数据+代码 可以作为毕设
    链表的问题
    当下测试行业中UI自动化面临的难点及如何解决
  • 原文地址:https://blog.csdn.net/qq_20013413/article/details/136359172