Kotlin 的 runCatching.. 也相当于 try..finally 吗?

Ita*_*ssi 26 kotlin

我想在某个代码块完成后运行清理代码,而不考虑异常。这不是可关闭的资源,我无法使用 try-with-resources (或 Kotlin 的use)。在 Java 中,我可以执行以下操作:

try {
  // ... Run some code
} catch(Exception ex) {
  // ... Handle exception 
} finally {
  // ... Cleanup code
}
Run Code Online (Sandbox Code Playgroud)

以下 Kotlin 代码等效吗?

runCatching {
  // ... Run some code
}.also {
  // ... Cleanup code
}.onFailure {
  // ... Handle exception
}
Run Code Online (Sandbox Code Playgroud)

编辑:添加了样板异常处理 - 我关心的是确保清理代码运行和可维护性。

Sam*_*Sam 36

有一个重要的区别,其中的代码runCatching包含提前返回。即使在 return 之后,块finally也会被执行,而没有这样的魔力。also

此代码运行时不会打印任何内容:

fun test1()
    runCatching {
        return
    }.also {
        println("test1")
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码运行时将打印“test2”:

fun test2() {
    try {
        return
    } finally {
        println("test2")
    }
}
Run Code Online (Sandbox Code Playgroud)


bro*_*oot 12

两个代码示例之间有一个很大的区别。在捕获/使用异常try...finally时传播异常。runCatching().also()为了使其相似,您必须将结果放在最后:

runCatching {
  // ... Run some code
}.also {
  // ... Cleanup code
}.getOrThrow()
Run Code Online (Sandbox Code Playgroud)

但它仍然不是真正的 1:1 等价物。它捕获所有异常只是为了重新抛出它们。因此,它的性能可能不如 simple try...finally

另外,我认为这对读者来说不太清楚。try...finally是处理异常的标准方法。通过使用runCatching()立即重新抛出,实际上会让稍后阅读此代码的人感到困惑。

你的问题听起来有点像你认为 Kotlin 没有try...finally,你需要寻找替代品。如果是这种情况,那么 Kotlin 当然有try...finally,我认为你应该使用它而不是runCatching().

  • 如果“runCatching”中的代码包含提前返回,则绝对存在这种边缘情况。即使在 return 之后,“finally” 块也会被执行,而“also”则没有这样的魔力。这是 Kotlin 游乐场链接:https://pl.kotl.in/gbqwRNIcV (9认同)