在他的演讲《编译器就是数据库》中,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
的东西?
或者有更好的方法来解决这个特定的问题吗?
Tree[Unit]
来处理未经类型化的树。这可以防止更多的错误(编译时与运行时错误),并且不需要你绕过类型检查器(嘿,这很有趣,不是吗)。Odersky在这里只是在做他自己的事情。 - user1804599