Почему этот необнуляемый val становится «обнуляемым»?

Итак, у меня есть простой класс обратного вызова:

class Callback<T>(
    val onResponse: (T) -> Unit,
    val onError:(Throwable)->Unit
)

Теперь я хочу реализовать метод, который обрабатывает ошибки. Может быть или не быть callback, который нужно вызвать.

private fun handleServerError(error:IServerError, callback:Callback<*>? = null){
    val reason = error.cause

    when(reason){
        is Because.ServerRejectsLogin -> {
            doAsync { uiThread { mainActivity.longToast("sorry, your session timed out. please log in again.") } }
            IntentManager.doLogin(mainActivity)
        }
        else -> callback?.onError(reason)
    }
}

Это вызывает у меня ошибку:

Reference has a nullable type ((Throwable) -> Unit)? use explicit ?.invoke() to make a function-like call, instead

То, что он, кажется, ожидает, это

else -> callback?.onError?.invoke(reason)

и я не совсем понимаю, почему. Разве того факта, что callback не является нулевым, не должно быть достаточно, чтобы вывести, что должна существовать ненулевая onError функция?

Чтобы добавить оскорбление к травме, если я напишу

else -> callback?.let{it.onError(reason)}

затем он принимает это, но не раньше, чем предупреждает меня, что я должен

remove redundant .let call

Shouldn't the fact that callback is not null be sufficient to derive that there must be a non-null onError function? хорошо, в вашем случае вы пометили callback как обнуляемый, поэтому существует вероятность, что он может быть нулевым
Rafa 21.02.2019 18:46
Сортировка hashmap по значениям
Сортировка hashmap по значениям
На Leetcode я решал задачу с хэшмапой и подумал, что мне нужно отсортировать хэшмапу по значениям.
2
1
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Синтаксис callback?.onError() был бы правильным, если бы вы вызывали функцию с именем onError для объекта callback с оператором безопасного вызова. Однако в этом случае вы сначала читаете свойство callback, а затем вызываете другую функцию для того, что вернуло свойство.

Итак, вместо выражения, состоящего всего из одного шага и двух частей:

callback   ?.onError()

На самом деле у вас есть выражение из трех частей с двумя операторами подряд:

callback   ?.onError   ()

Последний шаг здесь, (), — это вызов оператора invoke объекта, который возвращает onError:

callback   ?.onError   .invoke()

Однако, поскольку свойство onError читается оператором безопасного вызова, этот объект может быть null. В этом случае вы не можете использовать invoke в его форме оператора (то же самое касается любого другого оператора, кстати), поэтому вам нужно явно написать его, добавив еще один безопасный вызов:

callback   ?.onError   ?.invoke()

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

На самом деле, это имеет большой смысл. Спасибо. Вы уже упомянули об этом в трекере или мне добавить?

User1291 21.02.2019 19:02

Я еще не создавал тему для этого, так что вперед! Может быть, дайте ссылку и сюда.

zsmb13 21.02.2019 19:11

Другие вопросы по теме