Kotlin - предотвращение нулевых возвратов для ненулевых универсальных функций - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть следующий метод

fun <P> configure(property: KProperty1<R, P>, transform: (source: S) -> P) {
    ...
}

Если я вызову эту функцию с Foo::bar, где ::bar не обнуляем, функция преобразования позволяет мне вернуть что-то обнуляемое

configure(Foo::bar, { null })

Может ли метод быть реорганизован для предотвращения возврата функцией преобразования значений nullable, когда свойство не имеет значения null?

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Проблема на самом деле более общая:

configure(Foo::bar, { Object() })

тоже будет работать.Поскольку KProperty1 является ковариантным в параметре второго типа, KProperty1<R, String> (например) также является KProperty1<R, String?>, KProperty1<R, CharSequence> и т. Д. Это также относится к типу функции (source: S) -> P.Таким образом, что бы вы ни передавали (один параметр) transform, компилятор всегда найдет P такой, что типы будут соответствовать: наименьшая верхняя граница значений свойства и возвращаемые функцией функции.

Один довольно уродливыйОбходной путь, о котором я могу подумать, - это создание нековариантного типа оболочки:

class NonCov<A>(val value: A)

fun <P> configure(property: NonCov<KProperty1<R, P>>, transform: NonCov<(source: S) -> P)>) {
    ... // use property.value and transform.value
}

Тогда

class A(val x: String)

fun <P> configure(property: NonCov<kotlin.reflect.KProperty1<A, P>>, transform: NonCov<(source: A) -> P>) {}

fun main(args: Array<String>) {
    configure(NonCov(A::x), NonCov { "" }) // compiles
    configure(NonCov(A::x), NonCov { null }) // doesn't compile
}
0 голосов
/ 18 февраля 2019

Вместо

fun <P> configure(...)

Попробуйте это

fun <P : Any> configure(...)

Потому что из документ

Верхняя граница по умолчанию (еслине указано) Есть ли?

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