最后抛出异常时返回类型不匹配

问题描述 投票:2回答:3

我正在使用Kotlin 1.2.60。

val someString: String = try {

    String.format("Okay %s", "there") // or any function that returns String

} catch(exception: Exception) {

    try {
        // fun incrementErrorCount() { ... }
        incrementErrorCount() // [1] Error: Type mismatch: Inferred type is Unit but String was expected
    } finally {
        throw exception
    }

    // throw exception // [2] Fixes the type mismatch when uncommented, but raises Warning: Unreachable code
}

我在1上遇到类型不匹配错误,因为它期望incrementErrorCount()返回一个String - 但返回类型无关紧要,因为无论如何它总是会重新抛出exception

我添加了2,它修复了类型不匹配错误,但引发了一个无法访问的代码警告,因为该函数永远不会超过throw中的finally

我究竟做错了什么?如何在没有错误或警告的情况下编译它?

kotlin
3个回答
2
投票

有关Kotlin Reference的信息,请参阅try-catch-finally,您会看到:

try表达式的返回值是try块中的最后一个表达式或catch块(或块)中的最后一个表达式。 finally块的内容不会影响表达式的结果。

所以这意味着虽然你的意图是正确的,并且没有办法从你的第二个try块返回,但Kotlin编译器仍然会将Unit作为它的返回值而不是由于finally块的规范而修改它。

为了使编译器意识到catch块将始终返回Nothing这一事实,您需要将throw移出finally块。


0
投票

try-catch是Kotlin的一个表达。如果try块成功运行而不抛出任何内容,则返回其最后一个值。如果它抛出异常,则返回catch块的最后一个值。

在你的情况下,如果String.format没有抛出异常,它的结果将从第一个try-catch返回,你很好。这是一条简单的路线。

如果String.format抛出异常,则返回catch块的最后一个表达式,这是第二个嵌套的try-finally本身。这可以通过两种方式结束:

  • 如果嵌套的try块成功运行,则它的最后一个表达式(在本例中为incrementErrorCount)是它的计算结果,然后该调用的结果将被赋值给someString。这是你得到的类型错误,看起来incrementErrorCount没有返回String来分配。
  • 如果嵌套的try失败,则抛出异常,完全取消someString的赋值。

添加行[2]修复了你的错误,因为嵌套的try-catch没有被用作分配给someString的值,它刚刚运行并且throw表达式取消了someString的整个赋值。


0
投票

我假设您所需的逻辑是,如果String.format失败,您将抛出异常,但也会增加错误计数。在这种情况下,我认为你需要(未经测试)......

val someString: String = try {

    String.format("Okay %s", "there") // or any function that returns String

} catch(exception: Exception) {

    try {
        // fun incrementErrorCount() { ... }
        incrementErrorCount()
    } 
    catch (dontCare: Exception) {
    }

    throw exception 

}
© www.soinside.com 2019 - 2024. All rights reserved.