我正在使用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 警告,因为该函数永远不会超出throw
在finally
中。
我在做什么错?我如何才能在没有错误或警告的情况下进行编译?
答案 0 :(得分:2)
查看try-catch-finally
的{{3}},您会看到:
try
表达式的返回值要么是try
块中的最后一个表达式,要么是catch
块(或多个块)中的最后一个表达式。finally
块的内容不会影响表达式的结果。
因此,这意味着尽管您的意图是正确的,并且无法从第二个try
块返回,但Kotlin编译器仍将Unit
作为其返回值,并且不会修改它符合finally
块的规范。
要使编译器意识到catch
块将始终返回Nothing
的事实,您需要将throw
从finally
块中移出。
答案 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
}