1️⃣ Result 类型简介
Swift 的 Result 是一个泛型枚举:
enum Result<Success, Failure: Error> {
case success(Success)
case failure(Failure)
}
success包含成功值failure包含错误- 可用
map、flatMap、mapError等方法进行组合和转换 - 支持纯函数式链式处理,无需显式
try/catch
2️⃣ 使用 Result 的基本示例
假设有一个字符串转 Int 的函数,可能失败:
enum ParseError: Error {
case invalidNumber
}
// 返回 Result 类型
func parseInt(_ str: String) -> Result<Int, ParseError> {
if let n = Int(str) {
return .success(n)
} else {
return .failure(.invalidNumber)
}
}
// 使用
let result = parseInt("123")
switch result {
case .success(let value):
print("Parsed value:", value)
case .failure(let error):
print("Error:", error)
}
- 核心逻辑纯函数
- 错误封装在
Result中,而不是抛出副作用
3️⃣ 链式函数式处理
Result 支持 map / flatMap,可以安全组合多个可能失败的操作:
func increment(_ x: Int) -> Result<Int, ParseError> {
return .success(x + 1)
}
func double(_ x: Int) -> Result<Int, ParseError> {
return .success(x * 2)
}
// 流水线组合
let processed = parseInt("10")
.flatMap(increment) // 输入 Result<Int, Error> -> 输出 Result<Int, Error>
.flatMap(double)
switch processed {
case .success(let value):
print("Result:", value) // Result: 22
case .failure(let error):
print("Error:", error)
}
优势:
- 链式操作可读性强
- 错误自动传递,无需 try/catch
- 保持函数式风格,核心逻辑纯净
4️⃣ mapError 处理错误
如果想在链式中转换错误类型,也可使用 mapError:
enum AppError: Error {
case parseFailed
}
let finalResult = parseInt("abc") // 会失败
.mapError { _ in AppError.parseFailed }
switch finalResult {
case .success(let value):
print("Value:", value)
case .failure(let error):
print("Mapped Error:", error) // Mapped Error: parseFailed
}
- 可以统一错误类型,便于应用逻辑处理
5️⃣ 数组或集合上的函数式处理
可以结合 Result 和数组的 map / compactMap 处理多个可能失败的元素:
let inputs = ["1", "2", "three", "4"]
let results: [Result<Int, ParseError>] = inputs.map(parseInt)
// 只保留成功值
let successes = results.compactMap {
if case let .success(value) = $0 { return value }
else { return nil }
}
print(successes) // [1, 2, 4]
- 保持函数式流水线
- 错误不会中断整个流程
- 可选择集中处理失败或忽略失败
6️⃣ 优势总结
| 特性 | 优势 |
|---|---|
链式组合 (map / flatMap) | 可组合多个可能失败的操作 |
| 错误封装 | 无需抛出副作用,核心逻辑纯净 |
| 可测试 | 输入输出确定,易单元测试 |
| 与数组/集合组合 | 可函数式处理批量操作,灵活处理失败 |
💡 经验法则:
使用
Result封装可能失败的操作 → 链式函数组合 → 错误统一处理 → 保持函数式、纯函数逻辑