我是一个有用的助手,可以为您翻译文本。
我正在尝试使用Scala的类型系统,并发现了一个奇怪的情况。我有充分的理由相信,我不理解协变和协方差。
这是我的问题案例:
我有两个类,Point和ColorPoint,其中ColorPoint是Point的子类。
这个类将B类型转换为A类型,但是B应该是A的父类:
如果我写出这个代码:
我会期望这是不正确的,因为ColorPoint不是Point的超类型,但是scala并没有报错。
下一个:
如果我把这个写出来:
我认为这是错误的,但scala并没有抱怨。我会说Point不是ColorPoint的子类型。
我的推理正确吗?还是我漏掉了什么?
我正在尝试使用Scala的类型系统,并发现了一个奇怪的情况。我有充分的理由相信,我不理解协变和协方差。
这是我的问题案例:
我有两个类,Point和ColorPoint,其中ColorPoint是Point的子类。
class Point(val x : Int, val y : Int)
class ColorPoint(x : Int, y : Int, val red : Int, val green : Int, val blue : Int) extends Point(x,y)
这个类将B类型转换为A类型,但是B应该是A的父类:
class CoVariance[+A]{
def cast[B >: A](x : B) : A = {
return x.asInstanceOf[A]
}
}
这个类将B转换为A,但是B应该是A的超类型:
class ContraVariance[-A]{
def cast[B, A <: B](x : B) : A = {
return x.asInstanceOf[A]
}
}
案例1:
val co = new CoVariance[Point]
val color_point = new ColorPoint(1,2,3,4,5)
val point_co = co.cast(color_point)
println(point_co.x)
如果我写出这个代码:
// Covariance[Point] ->
// cast[B :> Point](x : B) : Point -> (fill in ColorPoint)
// Cast[ColorPoint :> Point] : Point
我会期望这是不正确的,因为ColorPoint不是Point的超类型,但是scala并没有报错。
下一个:
val contra = new ContraVariance[Point]
val color_point_contra = new ColorPoint(1,2,3,4,5)
val point_contra = contra.cast(color_point_contra)
println(point_contra.x)
如果我把这个写出来:
// ContraVariance[Point] ->
// cast[B, Point <: B](x : B) : Point -> (fill in ColorPoint)
// cast[ColorPoint, Point <: ColorPoint] : Point
我认为这是错误的,但scala并没有抱怨。我会说Point不是ColorPoint的子类型。
我的推理正确吗?还是我漏掉了什么?
f:A->B
和g:B->C
,我们有Type(f):Type[A]->Type[B]
和Type(g):Type[B]->Type[C]
,那么似乎成立Type(f.g)=Type(f).Type(g)
。 - Edgar Klerks