【发布时间】:2020-08-05 05:28:29
【问题描述】:
scala >
var a : Any = List(1,2,3,4,5,6,7,8,9,0)
我想迭代变量 a。因为它打印
1
2
3
4
5
6
7
8
9
0
【问题讨论】:
-
当你拥有 Any 的那一刻,你就失去了使用 Scala 的唯一理由,这是它强大的类型系统。为什么你首先要有一个Any?这是必须解决的代码异味,而不是变通方法。
scala >
var a : Any = List(1,2,3,4,5,6,7,8,9,0)
我想迭代变量 a。因为它打印
1
2
3
4
5
6
7
8
9
0
【问题讨论】:
只使用模式匹配:
a match {
case l: List[Int] => l.foreach(println)
}
P.S.:正如@IvanStanislavciuc 巧妙地注意到的那样,有一个警告:
警告:类型模式 List[Int](List[Int] 的底层)中的非可变类型参数 Int 未检查,因为它已被擦除消除 1
这是因为类型擦除,但是List需要一个类型参数,所以你也可以传递Any而不是Int。
【讨论】:
List[Int] 上的匹配并不完全正确,因为 Int 已被删除
诸如List 之类的集合通常使用map/foreach 高阶方法“迭代”,但是我们不能直接在a 上调用它们的原因是因为编译器认为a 的类型是Any因为我们明确指定了类型注释a: Any。
var a: Any = List(1,2,3,4,5,6,7,8,9,0)
| |
compile-time type runtime class
Any 不提供map/foreach API,所以我们能做的最好的就是执行一个运行时转换参考a 到类List[_] 像这样
if (a.isInstanceOf[List[_]]) a.asInstanceOf[List[_]].foreach(println) else ???
可以使用模式匹配等价地加糖
a match {
case value: List[_] => value.foreach(println)
case _ => ???
}
附带说明,由于类型擦除,我们只能检查“顶级”类List 而不能检查List[Int],因此a.isInstanceOf[List[Int]] 是有点误导,所以我更喜欢表达它a.isInstanceOf[List[_]]。
【讨论】: