【问题标题】:Scala - Iterate a Any variable which contains List()Scala - 迭代包含 List() 的 Any 变量
【发布时间】: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 scala-collections


【解决方案1】:

只使用模式匹配:

a match {
    case l: List[Int] => l.foreach(println)
}

P.S.:正如@IvanStanislavciuc 巧妙地注意到的那样,有一个警告:

警告:类型模式 List[Int](List[Int] 的底层)中的非可变类型参数 Int 未检查,因为它已被擦除消除 1

这是因为类型擦除,但是List需要一个类型参数,所以你也可以传递Any而不是Int

【讨论】:

  • 值得一提的是,List[Int] 上的匹配并不完全正确,因为 Int 已被删除
  • @IvanStanislavciuc 很好,我已经在我的回答中添加了它,谢谢!
【解决方案2】:

诸如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[_]]

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-01
  • 2018-02-20
  • 2020-02-16
  • 1970-01-01
  • 2021-04-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多