元组不必是同质的,编译器也没有尝试在元素1之间应用魔法类型统一。以这种异构元组 ( )(1, "hello")
为例。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) )
在这种特殊情况下isInstanceOf[Int]
,可用于细化类型 - 从Any
类型系统给我们的 - 因为我们知道,通过手动代码检查,它对给定的元组“是安全的”。
下面是对所涉及的迭代器/类型的另一种看法:
(1, 2) // -> Tuple2[Int,Int]
.productIterator // -> Iterator[Any]
.map(_.asInstanceOf[Int]) // -> Iterator[Int]
.foreach(x => println(x+1))
虽然我建议将元组视为同质元素的有限集合而不是序列,但可以使用与处理任何Iterator[Any]
诸如使用模式匹配(例如match
)根据实际对象类型进行区分的规则相同的规则。(在这种情况下,代码使用隐式 PartialFunction。)
(1, "hello").productIterator
.foreach {
case s: String => println("string: " + s)
case i: Int => println("int: " + i)
}
1虽然在这种情况下可以使编译器统一类型,但这听起来像是一种特殊情况,需要额外的工作才能获得最小的收益。通常,像列表这样的序列 - 而不是元组 - 用于同质元素,编译器/类型系统正确地为我们提供了类似的东西List(1,2)
(List[Int]
按预期输入)。