dee*_*imo 0 iterator scala scala-collections
在scala中,我们可以通过以下方式在元组上获得迭代器
val t = (1, 2)
val it = t.productIterator
Run Code Online (Sandbox Code Playgroud)
乃至
it.foreach( x => println(x.isInstanceOf[Int]) )
Run Code Online (Sandbox Code Playgroud)
返回true,因为不使用asInstanceOf [Int],我们无法对迭代器值执行简单的操作,因为
it.foreach( x => println(x+1) )
Run Code Online (Sandbox Code Playgroud)
返回错误:类型不匹配;找到:Int(1)必需:字符串
我了解Integer与Int的问题,但是isInstanceOf [Int]的有效性仍然有些令人困惑。
在元组上执行这些操作的最佳方法是什么?请注意,元组可以混合使用诸如整数和双精度之类的类型,因此转换为列表可能并不总是可行。
元组不必是同质的,并且编译器也没有尝试在元素1之间应用魔术类型统一。采取(1, "hello")作为例如AA异质元组的一个例子(Tuple2[Int,String])。
这意味着x键入为Any(不是Int!)。尝试it.foreach( (x: Int) => println(x) )使用原始元组,以获得更好的错误消息,指示迭代器在元组元素的类型上不是统一的(是Iterators[Any])。报告的错误应类似于:
error: type mismatch;
found : (Int) => Unit
required: (Any) => ?
(1, 2).productIterator.foreach( (x: Int) => println(x) )
Run Code Online (Sandbox Code Playgroud)
在这种特殊情况下,isInstanceOf[Int]可以使用Any类型系统提供给我们的类型来改进类型,因为从手动代码检查中我们知道,使用给定的元组将“安全”。
这是涉及的迭代器/类型的另一种外观:
(1, 2) // -> Tuple2[Int,Int]
.productIterator // -> Iterator[Any]
.map(_.asInstanceOf[Int]) // -> Iterator[Int]
.foreach(x => println(x+1))
Run Code Online (Sandbox Code Playgroud)
尽管我建议将元组视为同质元素的有限集合,而不是序列,但是可以使用与处理任何规则相同的规则,Iterator[Any]例如使用match根据实际对象类型区分的模式匹配(例如)。(在这种情况下,代码使用了隐式的PartialFunction。)
(1, "hello").productIterator
.foreach {
case s: String => println("string: " + s)
case i: Int => println("int: " + i)
}
Run Code Online (Sandbox Code Playgroud)
1虽然在这种情况下可以使编译器统一类型,但这听起来像是一种特殊情况,需要额外的工作才能获得最小的收益。通常,类似列表(而不是元组)之类的序列用于同质元素,并且编译器/类型系统正确地为我们提供了对类似List(1,2)(如List[Int]所期望的那样键入)的改进。
| 归档时间: |
|
| 查看次数: |
9745 次 |
| 最近记录: |