在Scala案例语句中键入捕获

时间:2014-01-02 19:05:12

标签: scala

考虑下面的Scala代码:

type i = Integer
val s1: List[Any] = List(1, "two")
s1 collect { case e: i => e } foreach (e => println(s"$e, ${e.getClass}"))

val s2: List[List[Any]] = List(List(1, "two"), List("one", 2))
s2 collect { case e: List[i] => e } foreach (e => println(s"$e, ${e.getClass}"))

val s3: List[List[Any]] = List(List(1, "two"), List("one", 2))
s3 collect { case e: List[`i`] => e } foreach (e => println(s"$e, ${e.getClass}"))

s1过滤i,所以它只打印i类型的元素,在我们的例子中是整数:

1, class java.lang.Integer

s2定义了一个名为i的新类型变量(它隐藏了原始i)并为其分配了当前的e类型。它匹配s2中的所有元素,因此输出:

List(1, two), class scala.collection.immutable.$colon$colon
List(one, 2), class scala.collection.immutable.$colon$colon

s3尝试仅过滤List [Integer]类型的元素,因为它将i视为稳定标识符,但由于删除,最终返回整个列表:

List(1, two), class scala.collection.immutable.$colon$colon
List(one, 2), class scala.collection.immutable.$colon$colon

现在,我不明白为什么在s1和s2案件中对待我的方式不同。在一种情况下,它引用已定义的类型变量,但在另一种情况下,它会创建一个新的类型变量。

1 个答案:

答案 0 :(得分:2)

它是类型擦除,与i别名或其稳定性无关

(顺便说一下,你真的不应该使用像这样的小写字母类型!)

如果替换别名并在带有-unchecked标志的REPL中运行,则会得到:

val s3: List[List[Any]] = List(List(1, "two"), List("one", 2))
s3: List[List[Any]] = List(List(1, two), List(one, 2))

s3 collect { case e: List[Integer] => e } foreach (e => println(s"$e, ${e.getClass}"))

<console>:9: warning: non-variable type argument Integer in type pattern List[Integer] is unchecked since it is eliminated by erasure
  s3 collect { case e: List[Integer] => e } foreach (e => println(s"$e,${e.getClass}"))
                       ^
List(1, two), class scala.collection.immutable.$colon$colon
List(one, 2), class scala.collection.immutable.$colon$colon