3-11.【函数式编程】什么是纯函数?在 Swift 中如何判断一个函数是否纯?

0 阅读2分钟

1️⃣ 什么是纯函数?

定义:纯函数是满足以下条件的函数:

  1. 输出仅依赖输入

    • 相同的输入必定产生相同的输出
    • 不依赖或修改外部状态
  2. 没有副作用(Side Effects)

    • 不修改外部变量
    • 不操作全局状态
    • 不做 I/O(打印、写文件、网络请求等)

总结

纯函数 = 可预测 + 无副作用


2️⃣ 纯函数示例

func square(_ x: Int) -> Int {
    return x * x
}
  • 输入:x
  • 输出:x * x(仅依赖输入)
  • 无副作用
    纯函数

带副作用的函数(非纯函数)

var counter = 0

func incrementCounter() -> Int {
    counter += 1
    return counter
}
  • 输出不仅依赖输入,还依赖全局变量 counter
  • 修改了外部状态
    不是纯函数

另一种非纯函数(I/O 副作用)

func printSquare(_ x: Int) -> Int {
    let result = x * x
    print(result)  // 打印属于副作用
    return result
}
  • 即使输出依赖输入,打印行为也是副作用
    不是纯函数

3️⃣ Swift 中判断函数是否纯

判断方法:

  1. 输入决定输出

    • 函数是否只使用参数计算结果
    • 不依赖全局变量、类属性、文件、网络等
  2. 无副作用

    • 不修改外部变量
    • 不打印、不写文件、不改数据库、不发网络请求
  3. 返回值类型

    • 函数最好返回值类型而非 Void(但返回值为 Void 也可以纯,只要无副作用)

示例:纯函数链式操作

let numbers = [1, 2, 3, 4, 5]

// 使用纯函数操作数组
let doubledSum = numbers
    .map { $0 * 2 }   // 纯函数
    .filter { $0 > 5 } // 纯函数
    .reduce(0, +)     // 纯函数

print(doubledSum) // 18
  • 每个闭包都是纯函数
  • 不修改外部状态
  • 相同输入总是产生相同输出

4️⃣ 优势

  1. 可预测性 → 相同输入必定输出相同
  2. 易测试 → 不需要设置环境,只测试函数即可
  3. 函数组合友好 → 可与 mapfilterreduce 等函数式操作安全组合
  4. 并发安全 → 无副作用,天然线程安全

总结判断纯函数的方法

  • 输出只依赖输入? ✅
  • 无副作用? ✅
  • 可重复执行得到相同结果? ✅ → 纯函数