1️⃣ 定义错误类型和函数
import Foundation
enum ParseError: Error {
case invalidNumber
}
enum AppError: Error {
case parseFailed
case negativeValue
}
// 函数 1:字符串转 Int
func parseInt(_ str: String) -> Result<Int, ParseError> {
if let n = Int(str) {
return .success(n)
} else {
return .failure(.invalidNumber)
}
}
// 函数 2:增加 10,但不能为负
func addTen(_ x: Int) -> Result<Int, AppError> {
let result = x + 10
if result >= 0 {
return .success(result)
} else {
return .failure(.negativeValue)
}
}
// 函数 3:翻倍
func double(_ x: Int) -> Result<Int, AppError> {
return .success(x * 2)
}
parseInt返回Result<Int, ParseError>addTen和double返回Result<Int, AppError>- 我们将演示 链式调用 + 错误映射
2️⃣ 链式调用 + flatMap
let input = "5"
let result = parseInt(input)
// 将 ParseError 映射为 AppError
.mapError { _ in AppError.parseFailed }
// 链式调用 addTen
.flatMap(addTen)
// 链式调用 double
.flatMap(double)
switch result {
case .success(let value):
print("Final Result:", value)
case .failure(let error):
print("Error:", error)
}
解释
-
parseInt可能失败 → 返回Result<Int, ParseError> -
使用
mapError将ParseError映射为统一的AppError -
使用
flatMap(addTen)链式调用- 如果前一步成功 → 执行
addTen - 如果失败 → 错误直接传递
- 如果前一步成功 → 执行
-
使用
flatMap(double)链式调用翻倍 -
最终
result是Result<Int, AppError>
3️⃣ 测试不同输入
let inputs = ["5", "-20", "abc"]
for input in inputs {
let result = parseInt(input)
.mapError { _ in AppError.parseFailed }
.flatMap(addTen)
.flatMap(double)
switch result {
case .success(let value):
print("Input:", input, "=>", value)
case .failure(let error):
print("Input:", input, "=> Error:", error)
}
}
输出示例:
Input: 5 => 30 // (5 + 10) * 2
Input: -20 => Error: negativeValue // (-20 + 10 < 0)
Input: abc => Error: parseFailed // 无法解析
4️⃣ 优势
- 链式调用无需嵌套
switch或try/catch - 错误通过
mapError/flatMap自动传递 - 核心逻辑保持 纯函数 + 函数组合
- 易于测试每个单独函数