强制类型参数在声明站点协变时在使用站点不变

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 不变。我知道您可以使用 outin 作为方差加宽器,但我无法弄清楚如何指定我想在这种情况下用不变性覆盖 KProperty1 上的协变注释。

值得注意的是,它与 KMutableProperty1 配合使用效果很好,因为它在 R 中是不变的。但是我的代码也需要使用非可变属性。

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

这在 Kotlin 中目前是不可能的。事实上,有一个内部注释可以启用此行为(导致编译器报告错误,如果推断出 Any 尽管在调用站点的任何地方都没有提到它)并且它在 [=11= 中的几个地方使用], 但仍然不鼓励在标准库之外使用它。

我们计划制作此注释 public。更多详情,请查看KT-13198.