我正在 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
中是不变的。但我的代码也需要使用不可变的属性。
对于上下文,我正在构建一些生成数据库查询的东西,这就是为什么我需要该值成为属性类型的子类,即使我实际上没有写入该属性,但这个问题更一般比我具体的属性(property)处理案例。
最佳答案
目前这在 Kotlin 中是不可能的。事实上,有一个内部注释可以实现此行为(如果推断出 Any
,尽管在调用站点中没有提到它,则导致编译器报告错误),并且它在 kotlin-stdlib
,但仍然不鼓励在标准库之外使用它。
我们计划公开此注释。更多详情请查看KT-13198 .
关于generics - 当类型参数在声明站点协变时,强制类型参数在使用站点保持不变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47191898/