используя стандартную функцию let и оценивая окончательный статус в блоке let как null при использовании оператора elvis - PullRequest
0 голосов
/ 05 августа 2020

Я играю с takeIf и позволяю стандартной функции mimi c оператор if / else.

После некоторого исследования я заметил некоторое неожиданное поведение, если последний оператор в блоке let возвращает null тогда elvis будет оценен как null и вызовет showError ().

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

val person: Person? = Person(isAdult = true)

Работает как ожидалось

if(person != null && person.isAdult) {
    showPerson(person)
}
else {
    showError()
}

Вопрос? Это вызовет showPerson, а затем showError, поскольку :: ShowPerson вернет null в последнем операторе

person?.takeIf { it.isAdult }
    ?.let { ::showPerson }
    ?: run { showError() }

Вопрос? Это покажет ошибку

person?.takeIf { it.isAdult }
    ?.let(::showPerson)
    ?: showError()

Работает как ожидалось

if(person != null && person.isAdult) {
    showPerson(person)
    hideProgressWithSuccess()
}
else {
    showError()
    hideProgress()
}

Вопрос? Это покажетPerson, а затем hideProgressWithSuccess, поскольку hideProgressWithSuccess является последним оператором и ничего не возвращает. Я предполагаю, что это работает так, как ожидалось, поскольку последний оператор не возвращает null

person?.takeIf { it.isAdult }
    ?.let { it: Person ->
        showPerson(it)
        hideProgressWithSuccess()
    }
    ?: run {
        showError()
        hideProgress()
    }


class Person(val isAdult: Boolean = true)

Явно возвращает null для проверки этого сценария

fun showPerson(person: Person): String? {
    println(person)
    return null
}

fun showError() {
    println("Person Error")
}

fun hideProgressWithSuccess() {}

fun hideProgress() {}

1 Ответ

3 голосов
/ 05 августа 2020

В традиционном операторе «if condition then action1 else action2» выполнение action2 зависит только от условия, а не от того, что вы могли бы сделать в action1, и выполняется только одно из action1 или action2.

Да, функция let возвращает результат выражения, и результат может быть нулевым или ложным. Поэтому, если вы используете после него оператор elvis, вы не получите строгое семанти «if..then..else» c.

Вы все равно можете получить семанти «if» c, если вы используйте функцию also или apply вместо let. Эти функции просто возвращают сам объект, независимо от того, что вы делаете внутри них. Таким образом, мы можем быть уверены, что они что-то возвращают и что часть else оператора elvis не выполняется.

Вы можете увидеть обзор различных функций области видимости в этой таблице, это помогает вам решить, какую функцию использовать, в зависимости от того, что вы хотите, чтобы они возвращали, и если вы хотите использовать внутри них «это» или «это».

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