Scala既存类型语法:
既存类型具有 T forSome {Q}的形式,Q 是一个类型声明的序列。设t1[tps1]>:L1<:U1,...,tn[tpsn]>:Ln<:Un 是 Q 中声明的类型(任何类型参数部分[tpsi]都可以没有)。每个类型 ti 的域都包含类型 T 和既存子句 Q。类型变量 ti 就称为在类型 T forSome {Q}中被绑定。在 T 中但是没被绑定的类型变量就被称为在 T 中是自由的。
T forSome {Q}的类的实例就是类 σT,σ 是 t1,...,tn 上的迭代,对于每一个 i,都有 σLi<:σti<:σUi。既存类型 T forSome{Q}的值的集合就是所有其类型实例值的集合的合集。
T forSome {Q}的斯科伦化是一个类实例 σT,σ 是[t‟
1/t1,..., t‟n/tn上的迭代,每个 t‟是介于 σLi和 σUi 间的新的抽象类型
简化规则
既存类型遵循以下四个等效原则:
在值上的既存量化
为了语法上的方便,在既存类型上的绑定子句可以包括值声明 val x: T。既存类型T forSome { Q; val x: S; Q‟} 是 T‟ forSome { Q; type t <: S withSingleton; Q‟}的简写形式,此处 t 是一个新的类型名,T‟是将 T 中所有 x.type 用t 代替的结果
既存类型的占位符语法
语法:
WildcardType ::= „_‟ TypeBoundsScala 支持既存类型的占位符语法。通配符类型的形式为 _>:L<:U。两个边界均可忽略。如果下界>:L 被忽略则>:scala.Nothing。如果上界<:U 被忽略则用<:scala.Any。通配符类型是既存限定类型变量的简写,既存的限定条件是内涵的。
通配符类型只能作为参数化类型的类型参量出现。设 T=p.c[targs,T,tags‟]是一个参数化类型,targs,targs‟可以为空,T 是一个通配符类型_>:L<:U。那么 T 等价于
以下既存类型:
p.c[tags,t,tags‟] forSome { type t >:L<:U}t 是一个新的类型变量。通配符类型可以作为中缀类型,函数类型或元组类型的一部分出现。它们的扩展也就是等价参数化类型的扩展
列表中的后两个类型是等价的。使用通配符语法的另一种形式是:
Ref[_ <: java.lang.Number]
Ref[(_ <: Outer with Singleton)# T]
示例 3.2.6 类型 List[List[_]]等价于既存类型:
List[List[t] forSome { type t }]
示例 3.2.7 假定有协变类型:
class List[+T]
类型:
List[T] forSome { type T <: java.lang.Number }
应用上面的第四条简化规则,上式等价于:
List[java.lang.Number] forSome { type T <: java.lang.Number }
如果再应用上面的第二和第三条简化规则,上式可化为:
List[java.lang.Number]