为什么Scala中的元组会被遍历?

时间:2016-06-28 12:21:06

标签: scala tuples traversal

假设我创建了一个Tuple6

val tup = (true, 1 , "Hello" , 0.4 , "World" , 0 )
tup: (Boolean, Int, String, Float, String, Int)

我可以使用._<position>来访问元组的元素 tup._1tup._2等等。但为什么呢

for (i <- 1 to 6)
     println(tup._i)

给我一​​个错误说

value _i is not a member of (String, Int, Boolean, String, Double, Int)

我知道明确指出元组不可迭代,但如果._1有效,那么._i是否应该以同样的方式工作?

4 个答案:

答案 0 :(得分:8)

这一切归结为类型

您希望动态访问者(例如_<position>)具有哪种类型?在一般情况下,唯一有效的是Any。在像Scala这样的强类型语言中,这对大多数用途来说都是无用的。

好消息是可以以类型安全的方式处理问题 - 例如, HList-style tuple handling中的shapeless

但是,标准的Scala库中没有这样的机制(禁止重组元编程,如宏)。

答案 1 :(得分:6)

对于元组,有一个productIterator方法,让您有机会迭代元组的元素。但显然这种迭代的每个元素都是Any

类型

答案 2 :(得分:3)

  

我理解明确指出元组不可迭代,但如果._1有效,那么._i不应该以相同的方式工作吗?

为什么要这样?在一种情况下,您调用方法_1(确实存在),在另一种情况下,您调用方法_i(不存在)。调用两种不同的方法通常“以相同的方式工作”,特别是如果其中一种方法甚至不存在。

答案 3 :(得分:1)

您可以提供Iterator[U],其中U是元组的T1Tn类型的最小上限。

implicit class FancyTuple2[T1,T2,U](private val tuple: (T1 with U,T2 with U)) extends AnyVal { 
  def iterator: Iterator[U] = Iterator(tuple._1, tuple._2)
}

你必须为每个你需要元组的arity编写(或生成)这个。