Нулевая ошибка безопасности отображается после проверки на ноль - PullRequest
0 голосов
/ 17 октября 2019

Я выполняю функцию (listOf(matchUid, first_name, gender, matchBio, age).any { it == null }), которая проверяет, являются ли какие-либо из переданных переменных null:

private fun getMatchData(doc: DocumentSnapshot){
    val matchUid = if (isUser1) doc.getString("user2") else doc.getString("user1")
    val first_name = if (isUser1) doc.getString("user2name") else doc.getString("user1name")
    val gender = if (isUser1) doc.getString("user2gender") else doc.getString("gender")
    val matchBio = if (isUser1) doc.getString("user2bio") else doc.getString("user1bio")
    if ( listOf(matchUid, first_name, gender, matchBio, age).any { it == null } ) return goOffline()
    if (matchUid == null) return goOffline()
    if (!isUser1) Group = Group().apply {
        id = doc.id
        user1 = matchUid
        user2 = user.uid
        match = User(matchUid, first_name, gender, null, true)
    } 

Даже при проверке этого first_name и gender имеют красный цветподчеркивается компилятором из-за нулевой безопасности. matchUid не имеет красной линии, потому что я явно проверяю наличие нулевой строки в ней ниже.

Почему компилятор все еще выдает нулевое предупреждение после того, как я уже проверил его?

1 Ответ

2 голосов
/ 17 октября 2019

Итак, проблема в том, что компилятор недостаточно умен, или ... мы не предоставляем достаточно информации.

В вашем случае проблемный вызов, когда вы гарантируете, что firstName и genderне ноль:

if (listOf(matchUid, firstName, gender, matchBio, age).any { it == null }) return goOffline()

Если вы измените его на простую цепочку нулей, он будет работать правильно:

if (matchUid == null || firstName == null || gender == null || matchBio == null || age == null) return goOffline()

Итак, почему это так? Компилятор просто не знает, что listOf(vararg objects: Any?).any { it == null } означает, что ни один из этих объектов не является нулевым. Итак, что мы можем сделать?

Kotlin 1.3 дал нам прекрасную возможность написать contracts, который является подсказкой для компилятора, который, например, если f(x) возвращает true означает, что xненулевой. Но, к сожалению, контракты не поддерживают аргумент varargs (или я не нашел способ сделать это).

Итак, в вашем случае вы можете заменить ваш вызов цепочкой одиночной проверки нуля.

...