Kotlin, неправильный оператор Elvis вызывается при выполнении вложенной проверки обнуляемости - PullRequest
0 голосов
/ 15 марта 2019

Я обнаружил, что в случае ниже блока Элвиса вызывается , когда вызывается, когда фактически это относится к проверке внешней обнуляемости

val outer : String? = ""
val inner : String? = null

outer?.let {
    inner?.let {
        // do something
    }
} ?: System.out.println("Outer else")

Внешнее остальное

Добавление ветки Элвиса к внутренней проверке обнуляемости ведет себя так, как ожидалось:

outer?.let {
    inner?.let {
        // do something
    } ?: System.out.println("Inner else")
} ?: System.out.println("Outer else")

Inner else

Это ошибка Котлина?

Ответы [ 3 ]

3 голосов
/ 15 марта 2019

Код ведет себя как ожидалось.Левый операнд оператора ?: в вашем случае -

outer?.let {
    inner?.let {
        // do something
    }
}

outer - не нуль, поэтому будет выполнен внешний блок let.inner равно нулю, следовательно, второй let не будет вызван, а возвращаемое значение внешнего блока будет равно нулю.Это делает все выражение равным нулю, поэтому выполняется правый операнд оператора ?:.

Во втором примере значение внешнего блока вычисляется как

inner?.let {
    // do something
} ?: System.out.println("Inner else")

Поскольку inner равен нулю, будет вызываться правый операнд ?:, который оценивается как Unit, и это значение внешнего блока.

1 голос
/ 15 марта 2019

Оператор Элвиса предназначен не только для проверок обнуляемости, он также оценивает результат оператора и, если null, он выполнит второе условие.

Другими словами, если inner?.let{} оценивается как null (если inner равно нулю или блок let возвращает ноль), вы получите печать Outer else.

Добавление оператора Элвиса во внутренний блок еще раз подтверждает это, так как кажется, что что-то в этом выражении оценивается как ноль.

1 голос
/ 15 марта 2019

Это не ошибка котлина.a?.let { expr } оценивается как ноль, если

  1. a равно нулю, или
  2. expr равно нулю

Если сложить все вместе, все ваше выражение будет оценено какследующим образом:

inner?.let { expr } оценивается как ноль, потому что inner является нулем (случай 1 выше) , поэтому outer?.let { ... } оценивается как ноль (случай 2 выше), потому что то, что внутри фигурных скобок, оценивается как ноль (bullet)11.) Итак, поскольку то, что осталось от оператора ?:, равно нулю (пункт 12), вычисляется внешнее выражение elvis.

Когда вы добавляете elvis послеinner?.let { }, outer?.let { } больше не возвращает ноль, возвращается Unit, поэтому внешний elvis не оценивается.Это понятно?

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