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

时间:2018-08-30 14:21:24

标签: kotlin

我正在使用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()返回一个字符串—但是返回类型无关紧要,因为它总是会仍然重新抛出exception

我添加了2,该错误修复了 Type不匹配错误,但引发了 Unreachable code 警告,因为该函数永远不会超出throwfinally中。

我在做什么错?我如何才能在没有错误或警告的情况下进行编译?

3 个答案:

答案 0 :(得分:2)

查看try-catch-finally的{​​{3}},您会看到:

  

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

因此,这意味着尽管您的意图是正确的,并且无法从第二个try块返回,但Kotlin编译器仍将Unit作为其返回值,并且不会修改它符合finally块的规范。

要使编译器意识到catch块将始终返回Nothing的事实,您需要throwfinally块中移出

答案 1 :(得分:0)

try-catch是Kotlin中的一个表达式。如果try块成功运行而没有抛出任何东西,则返回其最后一个值。如果引发异常,则返回catch块的最后一个值。

对于您来说,如果String.format没有引发异常,则其结果将从第一个try-catch返回,那么您就很好。这是简单的路线。

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

  • 如果嵌套的try块成功运行,则它的最后一个表达式(在这种情况下为incrementErrorCount)就是它的计算结果,然后将该调用的结果分配给{{1} }。这是您遇到的类型错误,看来someString没有返回incrementErrorCount来分配。
  • 如果嵌套的String失败,则会引发异常,从而完全取消try的分配。

添加第[2]行可解决您的错误,因为嵌套的someString不会用作分配给try-catch的值,它只是运行而someString表达式会取消整个分配的throw

答案 2 :(得分: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 

}