Scala2.13 REPL中多维数组生成的复杂类型语法含义咨询
Scala类型推导结果解释
基础语法前置
>::类型下界语法,T >: A表示类型T是A的父类型(超类型)<::类型上界语法,T <: B表示类型T是B的子类型forSome:Scala存在类型的声明语法,X forSome { 约束 }表示「存在满足约束的某类类型,当前值的类型为X」- 补充说明:Scala的
Array是不变类型,也就是说即使A <: B,也不存在Array[A] <: Array[B]的父子类型关系
分步拆解复杂类型
你的代码中将Array[Array[String]]类型的xx和Array[Array[Int]]类型的yy放入同一个数组ss,编译器需要推导ss的元素类型,也就是找Array[Array[String]]和Array[Array[Int]]的公共父类型,所以推导出了存在类型的表达式,我们从最内层往外拆解:
第一层:最内层约束
type _1 >: Int with String
这里的_1是内部占位类型,约束含义是:该类型必须是Int和String的公共父类型。Int和String的公共父类型最窄的就是Any,所以这层约束等价于_1 = Any。
第二层:中层存在类型
Array[_1] forSome { type _1 >: Int with String }
结合上一层的约束,这部分的含义是:存在某个是Int和String公共父类型的_1,当前类型是元素为_1的数组。因为Array是不变的,Array[String]和Array[Int]的公共父类型只能用这个存在类型表达,等价于元素类型为Int/String公共父类型的通配符数组,上界是Array[Any]。
第三层:外层约束
type _1 >: Array[Int] with Array[String] <: Array[_1] forSome { type _1 >: Int with String }
这里外层的_1是新的占位类型,约束含义是:
- 下界
>: Array[Int] with Array[String]:要求该类型必须是Array[Int]和Array[String]的公共父类型 - 上界
<: 中层存在类型:要求该类型不能超出中层推导的通配符数组的范围
第四层:最外层存在类型
Array[_1] forSome { (外层约束) }
也就是ss的元素类型:存在某个满足外层约束的_1,当前元素是元素为_1的数组。最终整个ss的类型就是这种元素的数组。
简化理解
这个复杂的类型是Scala编译器针对不变的Array容器,推导两个不同元素类型的Array的公共父类型时的完整表达,实际等价于Array[Array[_ >: Int with String <: Any]],你可以近似将ss当作Array[Array[Array[Any]]]来使用,编译器只是严格遵循不变性规则,用存在类型做了更精确的类型约束。
内容的提问来源于stack exchange,提问作者Goozo
相关产品推荐
相关产品推荐

