考虑以下 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 情况下以不同方式对待 i 。在一种情况下它引用已经定义的类型变量,但在另一种情况下,它创建一个新的类型变量。
最佳答案
这是类型删除,与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
关于scala - Scala case 语句中的类型捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20889949/