在他的演讲Compilers are Databases中,Martin Odersky提出了一个有趣的变异角点案例:
class Tree[-T] {
def tpe: T @uncheckedVariance
def withType(t: Type): Tree[Type]
}
T
被定义为逆变,因为将类型化的树(Tree[Type]
)视为无类型树(Tree[Nothing]
)的子类型是有用的,而不是另一个四处走动。
通常,Scala编译器会抱怨T
显示为tpe
方法的返回类型。这就是为什么Martin用@uncheckedVariance
注释来关闭编译器。
以下是转化为Kotlin的例子:
abstract class Tree<in T> {
abstract fun tpe(): T
abstract fun withType(t: Type): Tree<Type>
}
正如预期的那样,Kotlin编译器抱怨T
出现在'out'位置。
Kotlin有类似于@uncheckedVariance
的东西吗?
或者有更好的方法来解决这个特殊问题吗?
答案 0 :(得分:9)
Kotlin有一个@UnsafeVariance
注释,相当于scala中的@uncheckedVariance
:
abstract class Tree<in T> {
abstract fun tpe(): @UnsafeVariance T
abstract fun withType(t: Type): Tree<Type>
}