Возвращаемое несоответствие типов при генерации исключения в finally - PullRequest
0 голосов
/ 30 августа 2018

Я использую 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, который исправляет ошибку Несоответствие типов , но вызывает предупреждение Недоступный код , поскольку функция никогда не выходит за пределы throw в finally.

Что я делаю не так? Как я могу получить это для компиляции без ошибок или предупреждений?

Ответы [ 3 ]

0 голосов
/ 30 августа 2018

Я предполагаю, что желаемая вами логика заключается в том, что в случае сбоя 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 

}
0 голосов
/ 30 августа 2018

См. Kotlin Reference для try-catch-finally, и вы увидите:

Возвращаемое значение выражения try является либо последним выражением в блоке try, либо последним выражением в блоке catch (или блоками). Содержимое блока finally не влияет на результат выражения.

Таким образом, это означает, что, хотя ваше намерение верно, и нет никакого способа вернуться из вашего второго блока try, компилятор Kotlin все равно примет Unit в качестве возвращаемого значения и не изменит его из-за спецификации finally блок.

Чтобы компилятор знал, что блок catch всегда будет возвращать Nothing, вам необходимо переместить throw из блока finally .

0 голосов
/ 30 августа 2018

try-catch - это выражение на языке котлин. Если блок try работает успешно, ничего не выбрасывая, возвращается его последнее значение. Если возникает исключение, возвращается последнее значение блока catch.

В вашем случае, если String.format не выбрасывает исключение, его результат возвращается с первого try-catch, и вы в порядке. Это легкий маршрут.

Если String.format выдает исключение, возвращается последнее выражение блока catch, которое является вторым вложенным try-finally. Это может закончиться двумя способами:

  • Если вложенный блок try выполняется успешно, его последнее выражение (в данном случае incrementErrorCount) - это то, что он вычисляет, и тогда результат этого вызова будет присвоен someString. Это ошибка типа, которую вы получаете, похоже, incrementErrorCount не возвращает String для назначения.
  • Если во вложенном try произойдет сбой, вы выдаете исключение, отменяя назначение someString в целом.

Добавление строки [2] исправляет вашу ошибку, потому что вложенное try-catch не используется в качестве значения для присваивания someString, оно просто выполняется, а выражение throw отменяет все присвоение someString.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...