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) }
什么是纯函数
纯函数是指一个函数,给定相同的输入,总是返回相同的输出,并且没有任何可观察的副作用。不取决于系统状态,也不会对系统状态进行修改。 这类函数具有参数透明性、可测试性、并行性等诸多优秀特性, 所以我们偏好纯函数。但是只有纯函数也是不可能的, 我们必然会和外界进行交互, 所以只能尽可能得进行隔离。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)) }
由于我们隔离了系统依赖, 测试变得非常简单
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") } }
The End