加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala逆变和协方差

发布时间:2020-12-16 09:06:24 所属栏目:安全 来源:网络整理
导读:我正在玩 scala的类型系统,发现了一个奇怪的案例.我有充分的理由相信,我不理解协变和协方差. 这是我的问题: 我有两个类,Point和ColorPoint,它是Point的子类. class Point(val x : Int,val y : Int)class ColorPoint(x : Int,y : Int,val red : Int,val gree
我正在玩 scala的类型系统,发现了一个奇怪的案例.我有充分的理由相信,我不理解协变和协方差.

这是我的问题:

我有两个类,Point和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,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

我也期望这是不正确的,但斯卡拉并没有抱怨.我会说Point不是ColorPoint的子类型.

我的推理是正确的还是我错过了什么?

解决方法

我认为你误解了协变和逆变的立场.它并不意味着您能够在某些类型之间进行转换,它只是建立参数化类型之间的继承关系.

您只能将类型参数标记为协变或逆变位置.当你说Container [A]时,你说如果A是B的子类型,你可以将Container [A]的所有实例视为Container [B]的子类型.这对于不可变容器类是有意义的:你可以想到列表[Person]是List [Employee]的父级.请注意,这并未说明任何关于施法规则的内容

逆变是相似的,但相反.如果你有Writer [-A],它说Writer [A]是Writer [B]的子类型,如果B是A的子类型.你可以看到这也是如何直观的:如果你有一个Writer [Person] as可以将Person写入某个目的地的东西,你有Writer [Employee]作为一个只能编写Employees的编写器,Writer [Employee]成为Writer [Person]的父亲是有道理的,因为写一个Person是一个子写一个完整的员工的任务,即使它与类型本身相反.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读