Generics 强制类型参数在声明位置为协变时在使用位置保持不变

Generics 强制类型参数在声明位置为协变时在使用位置保持不变,generics,reflection,kotlin,covariance,generic-variance,Generics,Reflection,Kotlin,Covariance,Generic Variance,我正在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 w

我正在
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)
}
数据类数据(val值:字符串)
fun KProperty1.神奇地设置(值:V){
this.javaField?.set(null,值)
}
趣味测试(){
//我希望这个不能编译
Data::value.setMagically(190)
}
编译器似乎在推断
R
的类型
Any
,这是完全有效的,因为
KProperty1:KProperty1

我想说的是,对于我的特殊情况,我实际上希望
V
是不变的。我知道您可以使用
out
in
作为方差加宽器,但我无法确定如何指定要在
KProperty1
上使用不变性覆盖协变注释

值得注意的是,它非常适合
KMutableProperty1
,因为这在
R
中是不变的。但是我的代码也需要处理不可变的属性


对于上下文,我正在构建一些生成数据库查询的东西,这就是为什么我需要将值作为属性类型的子类,即使我没有实际写入属性,但这个问题比我的特定属性处理案例更一般。

这在Kotlin中目前是不可能的。事实上,有一个内部注释支持这种行为(如果推断出
Any
,则编译器会报告一个错误,尽管调用站点中没有提到过它),并且在
kotlin stdlib
中的多个位置使用过它,但仍然不鼓励在标准库之外使用它


我们计划将此注释公开。有关更多详细信息,请查看。

我也在discussion.kotlinglang.org上交叉发布了这篇文章: