假设我创建了一个Tuple6
:
val tup = (true, 1 , "Hello" , 0.4 , "World" , 0 )
tup: (Boolean, Int, String, Float, String, Int)
我可以使用._<position>
来访问元组的元素
tup._1
和tup._2
等等。但为什么呢
for (i <- 1 to 6)
println(tup._i)
给我一个错误说
value _i is not a member of (String, Int, Boolean, String, Double, Int)
我知道明确指出元组不可迭代,但如果._1
有效,那么._i
是否应该以同样的方式工作?
答案 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
是元组的T1
到Tn
类型的最小上限。
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编写(或生成)这个。