这个问题在这里已有答案:
- Iterate Over a tuple 4个答案
在scala中,我们可以按如下方式获取元组上的迭代器
val t = (1, 2)
val it = t.productIterator
乃至
it.foreach( x => println(x.isInstanceOf[Int]) )
返回true,我们不能在不使用asInstanceOf [Int]的情况下对迭代器值进行简单的操作,因为
it.foreach( x => println(x+1) )
返回错误:类型不匹配;发现:Int(1)required:String
我理解Integer与Int的问题,但isInstanceOf [Int]的有效性仍有些令人困惑 .
在元组上执行这些操作的最佳方法是什么?请注意,元组可以混合使用带有双精度的整数类型,因此转换为列表可能并不总是有效 .
2 回答
元组不必是同质的,编译器不会尝试在elements1之间应用魔术类型统一 . 以
(1, "hello")
为例,说明这样一个异类元组(Tuple2[Int,String]
) .这意味着
x
被输入为Any
(不是Int
!) . 尝试it.foreach( (x: Int) => println(x) )
,使用原始元组,以获得更好的错误消息,指示迭代器未对元组元素的类型进行统一(它是Iterators[Any]
) . 报告的错误应类似于:在这种特殊情况下,
isInstanceOf[Int]
可以用来改进类型 - 从类型系统给我们的Any
- 因为我们知道,从手动代码检查,它将与给定元组一起"be safe" .这是另一个涉及的迭代器/类型:
虽然我建议将元组视为有限的同质元素集而不是序列,但是当处理任何
Iterator[Any]
时,可以使用相同的规则,例如使用区分实际对象类型的模式匹配(例如match
) . (在这种情况下,代码使用隐式PartialFunction . )1尽管可能使编译器统一这种情况下的类型,但这听起来像是一个需要额外工作以获得最小收益的特殊情况 . 通常,像列表这样的序列 - 而不是元组 - 用于同源元素,编译器/类型系统正确地为我们提供了一个很好的改进,例如
List(1,2)
(按预期键入List[Int]
) .还有另一种类型HList,就像元组和List all-in-one . 见shapeless .
我想,你可以接近你想要的东西: