Общие ограничения Kotlin - требуют, чтобы param был того же типа, что и другие - PullRequest
0 голосов
/ 20 февраля 2019

Допустим, у меня есть набор из двух pojo, например, так:

data class Test (
    var id : Long? = null
)

data class TestOther (
    var id : Long = 0,
    var isCool : Boolean = false
}

, а затем у меня есть инфиксная функция, например, так:

infix fun <T : Any?> KProperty<T>.equal(rhs : KProperty<T>) = BinaryExpression<Boolean>(this, rhs, EQUALS)

, тогда это прекрасно работает, когда я 'd ожидает:

Test::id equal TestOther::id

но так же, так как T - это все типы, расширяющие Any?:

Test::id equal TestOther::isCool

В любом случае можно указать общие ограничения, такие, что могут быть обнуляемые и не обнуляемые типыможно сравнивать, но объекты разных типов не могут без необходимости определять перегрузку для каждого возможного конкретного типа?

1 Ответ

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

Это невозможно сделать прямо сейчас.Вы можете следить за проблемой для получения более подробной информации https://youtrack.jetbrains.com/issue/KT-13198

Я вижу обходной путь здесь (аналогично тому, что было в проблеме).Идея состоит в том, чтобы обернуть KProperty<R> в класс-оболочку без отклонений.Как видите, тип KProperty имеет дисперсию out R, что в нашем примере работает против нас.Вы можете перейти по ссылке для получения подробных сведений об отклонении на стороне объявления в Kotlin https://kotlinlang.org/docs/reference/generics.html#declaration-site-variance

Временное решение работает так же строго, как и ожидалось

class KWrapper<R>(val p : KProperty<R>)
infix fun <T : KWrapper<R>, R> T.equal(rhs : T) = false
val <T> KProperty<T>.wrap get() = KWrapper(this)

val a = Test::id.wrap equal TestOther::id.wrap //fails: Long vs Long?
val b = Test::id.wrap equal Test::id.wrap //works
val c = Test::id.wrap equal TestOther::isCool.wrap // fails Long vs Boolean

Недостатком является то, что вам нужно использовать .wrap свойство расширения (или функция расширения) для левого и правого параметров отдельно

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