Несоответствие параметров универсального типа Kotlin: тип ввода не равен нулю, но ожидалось - PullRequest
0 голосов
/ 01 марта 2019

У меня есть класс оболочки данных с параметром T. В этом классе есть function с универсальным контейнером с nullable типом: T?(например, LiveData )

class Wrapper<T> {
   fun add (data: LiveData<T?>) {
    // ...
   }
}

В этом месте мне действительно нужен именно такой тип.Когда я пытаюсь использовать этот метод и передать ненулевой параметр типа:

class Program {
   fun get() {
      // some generic container, e.g. LiveData
      val data: LiveData<Int> = MutableLiveData()
      val wrapper = Wrapper<Int>()
      wrapper.add(data)
                  ^^^^ error
   }
}

это была ошибка «Несоответствие типов»: ссылка на изображение

Type mismatch: inferred type is LiveData<Int> but LiveData<Int?> was expected

Какс этим бороться?Как умно приводить универсальный параметр типа от ненулевого к обнуляемому?

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Вы можете исправить объявление класса Wrapper следующим

class Wrapper<T> {
   fun add (data: LiveData<T>) {
    // ...
   }

Я заменил T? на T в параметре типа LiveData.Таким образом, у вас могут быть типы Wrapper<Int> и Wrapper<Int?>.

Котлин сообщает обнуляемые типы (например, Int?) из необнуляемых типов, например Int.Вы можете проверить статью для более подробной информации: https://kotlinlang.org/docs/reference/null-safety.html

Второй вариант предлагается в предыдущем ответе использовать дисперсию.Может быть невозможно использовать для некоторых реализаций LiveData класс / интерфейс.
https://kotlinlang.org/docs/reference/generics.html

0 голосов
/ 01 марта 2019

Это ошибка, связанная с дисперсией : LiveData<Int?> может быть только подтипом LiveData<Int>, если вы сделаете T out переменную:

class LiveData<out T>

Общее правило таково: когда параметр типа T класса C объявлен как out, он может произойти только в out-position в членах C, но взамен C<Base> может безопасно бытьсупертип C<Derived>.

В «умных словах» говорится, что класс C ковариантен в параметре T или что T является параметром ковариантного типа.Вы можете думать о C как о производителе T, а НЕ как о потребителе T.

Но даже лучше просто изменить подпись addпринять LiveData<T>, если это не желательно.

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