我正在使用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 Reference的信息,请参阅try-catch-finally
,您会看到:
try
表达式的返回值是try
块中的最后一个表达式或catch
块(或块)中的最后一个表达式。finally
块的内容不会影响表达式的结果。
所以这意味着虽然你的意图是正确的,并且没有办法从你的第二个try
块返回,但Kotlin编译器仍然会将Unit
作为它的返回值而不是由于finally
块的规范而修改它。
为了使编译器意识到catch
块将始终返回Nothing
这一事实,您需要将throw
移出finally
块。
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
的整个赋值。
我假设您所需的逻辑是,如果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
}