I have class
class GenericClass[+T] (var x: T) {}
当我尝试编译它时,我得到:
Error:(6, 33) covariant type T occurs in contravariant position in type T of value x_=
class GenericCellImm[+T] (var x: T) {
如何解决?问题原因是什么?
协变泛型类型意味着如果你有类Base
和扩展Base
Child
,那么在GenericClass[Base]
是正确类型的每个上下文中,使用类型为GenericClass[Child]
的对象也将是正确的。粗略地近似,这意味着如果您的GenericClass[T]
提供只读 API,您可以进行+T
协变,因为返回Child
而不是Base
始终是安全的。但是,如果您的GenericClass[T]
中有一些可写的 API,则情况并非如此。请考虑以下代码:
def writeDefault(gc: GenericClass[Base]):Unit = {
gc.x = new Base()
}
如果gc
确实属于GenericClass[Base]
类型,则此代码是安全的,但如果GenericClass[Child]
,则会将类型为Base
的值写入键入Child
的字段,这会破坏预期的类型安全性。考虑
class Base(){}
class Child(childField:Int) extends Base {}
def bad():Unit = {
val gc = new GenericClass[new Child(1)]
writeDefault(gc)
println(gc.childField) // Oops! there is no childField in Base
}
这正是编译器不允许您的代码具有协方差的原因。
如果你想得到一些关于如何解决它的真正建议,你应该描述你试图解决的更高层次的问题。如果没有这样的描述,真的很难猜测是否只需要使用val
而不是var
来,或者你只需要完全消除协方差,或者你是否需要更复杂的代码。