强制类型参数在声明站点协变时在使用站点不变
Force type parameter to be invariant at use-site when it is covariant at declaration site
我正在 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)
}
编译器似乎正在为 R
推断类型 Any
,这是完全有效的,因为 KProperty1<*, String> : KProperty1<*, Any>
我想说的是,对于我的特殊情况,我实际上希望 V
不变。我知道您可以使用 out
和 in
作为方差加宽器,但我无法弄清楚如何指定我想在这种情况下用不变性覆盖 KProperty1
上的协变注释。
值得注意的是,它与 KMutableProperty1
配合使用效果很好,因为它在 R
中是不变的。但是我的代码也需要使用非可变属性。
对于上下文,我正在构建生成数据库查询的东西,这就是为什么我需要值是 属性 类型的子类,即使我实际上并没有写入 属性,但这个问题比我的具体问题更笼统,属性-处理案例。
这在 Kotlin 中目前是不可能的。事实上,有一个内部注释可以启用此行为(导致编译器报告错误,如果推断出 Any
尽管在调用站点的任何地方都没有提到它)并且它在 [=11= 中的几个地方使用], 但仍然不鼓励在标准库之外使用它。
我们计划制作此注释 public。更多详情,请查看KT-13198.
我正在 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)
}
编译器似乎正在为 R
推断类型 Any
,这是完全有效的,因为 KProperty1<*, String> : KProperty1<*, Any>
我想说的是,对于我的特殊情况,我实际上希望 V
不变。我知道您可以使用 out
和 in
作为方差加宽器,但我无法弄清楚如何指定我想在这种情况下用不变性覆盖 KProperty1
上的协变注释。
值得注意的是,它与 KMutableProperty1
配合使用效果很好,因为它在 R
中是不变的。但是我的代码也需要使用非可变属性。
对于上下文,我正在构建生成数据库查询的东西,这就是为什么我需要值是 属性 类型的子类,即使我实际上并没有写入 属性,但这个问题比我的具体问题更笼统,属性-处理案例。
这在 Kotlin 中目前是不可能的。事实上,有一个内部注释可以启用此行为(导致编译器报告错误,如果推断出 Any
尽管在调用站点的任何地方都没有提到它)并且它在 [=11= 中的几个地方使用], 但仍然不鼓励在标准库之外使用它。
我们计划制作此注释 public。更多详情,请查看KT-13198.