runCatching 链式调用

3 阅读1分钟

runCatching { ... }.getOrElse { ... } 是 Kotlin 提供的一种优雅处理异常的语法方式,封装了 try-catch 的逻辑,更适用于函数式风格的异常捕获。下面我将从用法、适用场景、对比 try-catch、实际案例四个方面讲清楚这段代码的优势和使用建议。


1. 基本用法

val result = runCatching {
    // 可能抛异常的代码
    riskyOperation()
}.getOrElse { exception ->
    // 出现异常时的默认值
    defaultValue
}
  • runCatching { ... }: 执行一个有可能抛异常的代码块
  • .getOrElse { ... }: 如果捕获到异常,就返回你提供的默认值

2. 使用场景

你可以在以下场景中考虑使用这段结构:

📌 场景一:替代 try-catch 获取默认值

val config = runCatching {
    loadConfigFromFile()
}.getOrElse {
    // 文件不存在、格式错误时使用默认配置
    Config.default()
}

📌 场景二:简洁地处理错误而不影响主流程

适合函数式风格链式调用:

val result = runCatching {
    remoteService.fetchData()
}.getOrElse {
    logger.warn("获取数据失败:${it.message}")
    emptyList()
}

📌 场景三:封装 API 层异常处理

可以把它放到 Repository 层封装网络请求:

fun getUser(): User = runCatching {
    api.getUserFromServer()
}.getOrElse {
    throw BusinessException("用户获取失败", it)
}

3. 和 try-catch 的对比

对比项try-catchrunCatching
可读性冗长简洁、链式
可组合性不支持链式支持链式调用如 getOrElse, onFailure 等
响应式风格更函数式
适用场景控制流程,逻辑复杂时更好单一 try 操作或链式返回时更优

4. 扩展:其他 runCatching 链式 API

runCatching {
    risky()
}.onSuccess {
    // 成功回调
}.onFailure {
    // 失败处理
}
val valueOrNull = runCatching {
    maybeNull()
}.getOrNull()

总结

使用 runCatching { }.getOrElse { } 的理由:

  • 代码更简洁优雅
  • 不破坏函数式/响应式链路
  • 易于统一错误处理和 fallback 策略