Синтаксис распространения Kotlin null не работает

#kotlin

#kotlin

Вопрос:

Я пытаюсь безопасно вызвать некоторые свойства обратного вызова, но IDE / компилятор жалуется на синтаксис.

Ссылка имеет обнуляемый тип ‘(() -> Unit)?’, используйте явный ‘?.invoke()’, чтобы вместо этого выполнить функциональный вызов

Объявление свойства:

 var onTick: ((millisUntilFinished: Long) -> Unit)? = null
var onFinish: (() -> Unit)? = null
  

Вызов:

 override fun onFinish() {
    // syntax #1
    if (parent.onFinish != null)
        parent.onFinish()
}

override fun onTick(millisUntilFinished: Long) {
    this.millisUntilFinished = millisUntilFinished
    // syntax #2
    parent?.onTick(millisUntilFinished)
}
  

Технические характеристики:

  • ОС: Windows
  • Версия Kotlin: 1.4.0-rc
  • Android Studio: 4.0.1

Пока что мой лучший вариант — использовать lateinit var , но это кажется неуместным в моем случае.

Комментарии:

1. Было бы проще всего изменить объявления на ненулевые, если это возможно.

Ответ №1:

Компилятор Kotlin предназначен для поддержки нулевой безопасности даже в случае многопоточности. Нет гарантии, что после parent.onFinish != null проверки он не был установлен null в каком-либо другом потоке, поэтому smart cast здесь не работает.

Как говорит компилятор, используйте явный ‘?.invoke()’:

 parent.onFinish?.invoke()
  
 parent.onTick?.invoke(millisUntilFinished)
  

Комментарии:

1. Черт возьми. Я запутался в синтаксисе. Я выполнял null propagation для ненулевой parent переменной, в то время как вместо этого я должен был делать это для ее свойства. Спасибо за ваш ответ 🙂