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上交叉发布了这篇文章: