Принудительно указать параметр типа, чтобы он был инвариантным на сайте использования, когда он ковариантен на сайте объявлений.
Я строю функцию расширения на KProperty1
, Функция должна принимать аргумент, расширяющий тип значения свойства (R
), даже если KProperty1
ковариантен в параметре типа R
,
Немного придуманный пример будет следующим, хотя мое использование более законно.
data class Data(val value: String)
fun <V> KProperty1<*, V>.setMagically(value: V) {
this.javaField?.set(null, value)
}
fun test() {
// I would like this to fail to compile
Data::value.setMagically(190)
}
Казалось бы, компилятор выводит тип Any
за R
, который полностью действителен, так как KProperty1<*, String> : KProperty1<*, Any>
Я хочу сказать, что для моего конкретного случая я действительно хочу V
быть инвариантным. Я знаю, что вы можете использовать out
а также in
как расширение дисперсии, но я не смог понять, как указать, что я хочу переопределить ковариантную аннотацию на KProperty1
с неизменностью для этого случая.
Стоит отметить, что он прекрасно работает с KMutableProperty1
, поскольку это инвариант в R
, Но мой код должен работать и с неизменяемыми свойствами.
Для контекста я создаю что-то, что генерирует запросы к базе данных, поэтому мне нужно, чтобы значение было подклассом типа свойства, даже если я не пишу в свойство, но этот вопрос является более общим, чем мой конкретный, дело об обработке имущества.
1 ответ
В настоящее время это невозможно в Котлине. На самом деле, есть внутренняя аннотация, которая включает это поведение (заставляет компилятор сообщать об ошибке, если Any
выводится, хотя нигде на сайте вызова не было упомянуто), и он используется в нескольких местах в kotlin-stdlib
, но использовать его за пределами стандартной библиотеки по-прежнему не рекомендуется.
У нас есть планы сделать эту аннотацию публичной. Для более подробной информации, пожалуйста, проверьте KT-13198.