3-22.【函数式编程】设计一个函数式流水线,处理一系列操作,遇到错误立即返回,并保证副作用可控。

7 阅读2分钟

设计一个 函数式流水线,实现以下目标:

  1. 处理一系列数据操作
  2. 遇到错误立即返回
  3. 保证副作用(打印、日志、网络等)集中可控
  4. 使用 Swift 的 Result 类型 + 纯函数

1️⃣ 定义错误类型和函数

import Foundation

// 定义错误类型
enum PipelineError: Error {
    case parseFailed
    case negativeValue
    case tooLarge
}

// 函数 1:字符串转 Int
func parseInt(_ str: String) -> Result<Int, PipelineError> {
    if let n = Int(str) {
        return .success(n)
    } else {
        return .failure(.parseFailed)
    }
}

// 函数 2:加 10,但结果不能为负
func addTen(_ x: Int) -> Result<Int, PipelineError> {
    let result = x + 10
    return result >= 0 ? .success(result) : .failure(.negativeValue)
}

// 函数 3:翻倍,但不能超过 100
func double(_ x: Int) -> Result<Int, PipelineError> {
    let result = x * 2
    return result <= 100 ? .success(result) : .failure(.tooLarge)
}
  • 每个函数都是 纯函数
  • 返回 Result,错误显式传递
  • 没有副作用

2️⃣ 构建函数式流水线

func processPipeline(_ input: String) -> Result<Int, PipelineError> {
    return parseInt(input)
        .flatMap(addTen)
        .flatMap(double)
}
  • 使用 flatMap 链式调用
  • 遇到 失败 → 立即返回失败,后续函数不执行
  • 保持纯函数逻辑

3️⃣ 执行副作用(可控打印/日志)

func runPipeline(_ input: String) {
    let result = processPipeline(input)
    
    switch result {
    case .success(let value):
        print("Pipeline Success:", value) // 副作用集中在这里
    case .failure(let error):
        print("Pipeline Error:", error)   // 副作用集中在这里
    }
}
  • 副作用仅在最外层执行
  • 核心流水线纯净,可测试

4️⃣ 测试流水线

let inputs = ["5", "-20", "abc", "50"]

for input in inputs {
    runPipeline(input)
}

输出示例

Pipeline Success: 30      // 5 -> 5+10=15 -> 15*2=30
Pipeline Error: negativeValue   // -20 -> -20+10=-10 -> fail
Pipeline Error: parseFailed     // abc -> cannot parse
Pipeline Error: tooLarge        // 50 -> 50+10=60 -> 60*2=120 > 100

5️⃣ 优势分析

特性优势
纯函数处理每个操作独立可测试,逻辑可复用
Result 错误传递遇到错误立即返回,自动短路,不需要 try/catch
副作用集中打印、日志集中在外层 runPipeline,核心逻辑无副作用
链式组合易扩展,可添加更多操作函数,如 subtractFive, square

💡 总结设计模式

  1. 核心操作函数 → 纯函数 + 返回 Result
  2. 流水线组合 → flatMap 链式调用,遇到失败立即返回
  3. 副作用 → 集中执行在最外层,核心逻辑保持纯净