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

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

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

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

什么是副作用

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

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

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

go 复制代码
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函数正式执行获取今天是周几。

go 复制代码
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))
}

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

go 复制代码
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")
	}
}
相关推荐
mONESY16 小时前
React 前端如何不傻等后端接口?
前端·javascript·后端
淡海水16 小时前
C#与常用数据结构源码剖析-全篇导览
开发语言·数据结构·unity·面试·职场和发展·c#
星火102416 小时前
【LangChain4j系列03】AI Services 高层抽象设计解析
人工智能·后端
星火102416 小时前
【LangChain4j系列04】Tools 工具调用机制详解
人工智能·后端
用户693717500138416 小时前
深夜炸场!DeepSeek 没发新模型,却重构了整个 Agent 生态
前端·后端·github
问天_观心16 小时前
python之uv库的学习
开发语言·python
郑州光合科技余经理16 小时前
餐饮预定系统架构拆解:订单链路、权限组织与私有化源码交付
java·开发语言·前端·数据库·人工智能·系统架构·php
在世修行17 小时前
从零打造 C# 工业视觉检测系统(十五):项目打包部署与进阶展望
开发语言·c#·视觉检测
Nebula_g17 小时前
JavaSE基础语法:特殊类(特殊情景下的设计模式)
java·开发语言·设计模式
不正经学生17 小时前
C语言大小端字节序:内存里字节的排列顺序
c语言·开发语言·arm开发·c++·算法·c#