您的位置:首页 > 编程语言 > Java开发

scala类型系统:协变与逆变

2017-02-13 23:49 246 查看
对于一个带类型参数的类型,比如 
List[T]
,如果对
A
及其子类型
B
,满足 
List[B]
也符合 
List[A]
的子类型,那么就称为covariance(协变),如果 
List[A]
是 
List[B]
的子类型,即与原来的父子关系正相反,则称为contravariance(逆变)

协变:
_____               _____________
|     |             |             |
|  A  |             |  List[ A ]  |
|_____|             |_____________|
^                       ^
|                       |
_____               _____________
|     |             |             |
|  B  |             |  List[ B ]  |
|_____|             |_____________|


逆变:
_____               _____________
|     |             |             |
|  A  |             |  List[ B ]  |
|_____|             |_____________|
^                       ^
|                       |
_____               _____________
|     |             |             |
|  B  |             |  List[ A ]  |
|_____|             |_____________|


如果一个类型支持协变或逆变,则称这个类型为variance(翻译为可变的或变型),否则称为invariant(不可变的)

在Java里,泛型类型都是invariant,比如 
List<String>
 并不是 
List<Object>
 的子类型。Java并不支持声明点变型(declaration-site
variance,即在定义一个类型时声明它为可变型,也称definition-site),而scala支持,可以在定义类型时声明(用加号表示为协变,减号表示逆变),如:
trait List[+T] // 在类型定义时(declaration-site)声明为协变


这样会把
List[String]
作为
List[Any]
的子类型。

不过Java支持使用点变型(use-site variance),所谓“使用点“,也就是在声明变量时:
List<? extends Object> list = new ArrayList<String>();


scala为了兼容java泛型通配符的形式,引入存在类型(existential type,后边再讲)时,也支持了使用点变型(use-site variance)
scala> val a : List[_ <: Any] = List[String]("A")
a: List[_] = List(A)


要注意variance并不会被继承,父类声明为variance,子类如果想要保持,仍需要声明:
scala> trait A[+T]

scala> class C[T] extends A[T]  // C是invariant的

scala> class X; class Y extends X;

scala> val t:C[X] = new C[Y]
<console>:11: error: type mismatch;
found   : C[Y]
required: C[X]
Note: Y <: X, but class C is invariant in type T.
You may wish to define T as +T instead. (SLS 4.5)


必须也对C声明为协变的才行:
scala> class C[+T] extends A[T]

scala> val t:C[X] = new C[Y]
t: C[X] = C@6a079142


对于协变与逆变的使用,参考《Effective Java》的PECS原则
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java scala
相关文章推荐