为什么可以';可以遍历Scala中的t元组吗?

为什么可以';可以遍历Scala中的t元组吗?,scala,tuples,traversal,Scala,Tuples,Traversal,假设我创建一个元组6: val tup = (true, 1 , "Hello" , 0.4 , "World" , 0 ) tup: (Boolean, Int, String, Float, String, Int) 我可以使用。像这样访问元组的元素 tup.\u 1和tup.\u 2等等。但是为什么呢 for (i <- 1 to 6) println(tup._i) 我明白有人明确指出,元组是不可编辑的,但如果\u 1有效,那么\u I不应该以同样的方式工作吗?这一切

假设我创建一个
元组6

val tup = (true, 1 , "Hello" , 0.4 , "World" , 0 )
tup: (Boolean, Int, String, Float, String, Int)
我可以使用
像这样访问元组的元素
tup.\u 1
tup.\u 2
等等。但是为什么呢

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

我明白有人明确指出,元组是不可编辑的,但如果
\u 1
有效,那么
\u I
不应该以同样的方式工作吗?

这一切归结为类型

您希望动态存取器(如
\uu
)具有什么类型?在一般情况下,唯一有效的是
Any
。在Scala这样的强类型语言中,这在大多数情况下都是无用的

好消息是可以以类型安全的方式处理此问题-请参阅中的中的


但是,在标准Scala库中没有这样的机制(除了宏等繁重的元编程)。

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

的,您可以提供一个
迭代器[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编写(或生成)这个

我知道有人明确指出,元组是不可编辑的,但是如果
\u 1
起作用,那么
\u I
不应该起同样的作用吗


为什么要这样做?在一种情况下,您正在调用方法
\u 1
(确实存在),在另一种情况下,您正在调用方法
\u i
(不存在)。调用两个不同的方法通常不会“以相同的方式工作”,特别是当其中一个方法甚至不存在时。

\u 1
中的
1
不是一个文字整数,而是一个任意标识符。它可以被称为
\u xyz
并做同样的事情,但那会让人困惑。@m-z很抱歉,我尝试了你的建议,但没有效果。这不是一个建议。@m-z哦,现在我明白了。ThanksTuples不应该被认为是集合,而是一种有许多成员的未命名类。但例如,我创建了一个元组,其中所有元素都是相同类型的,比如字符串,为什么它不工作?是不是因为元组被设计成只适用于任何类型?Yankee:你能想到很多情况下,这样的元组会比
列表
更好吗?您是否认为这些情况会证明额外的实现类型和API混淆是合理的(因为这是一个相当模糊的例外)?顺便说一句,不要误会我的意思——我在我的项目中有相当一部分使用了shapeless,正是出于这个目的,所以需求肯定是存在的。但是动态访问器无法以令人满意的方式处理它。在标准scala中有一种方法:
tuple.productIterator.foreach(println)
@Dima:我有一种预感,这个问题最终包含了函数等价的隐式假设,所以答案就是在这种情况下创建的,引导OP解决实际问题(显然,这一预感已得到证实)。顺便说一句,请注意这里的
productIterator
的所有示例是如何与
println
配对的?@mikolak它们与
println
配对是因为缺乏想象力,而不是因为任何特定的技术原因。考虑<代码> tuPL.ToeStudioTalp.Mult{{CaseX:INT=>X+1;Case}=>0 } < /代码>更好?是的,我的错。我不知道这是一个方法调用,@m-z的一条评论澄清了这一点。感谢您的详细解释。使用类似方法的另一种方法是:
for(i
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)
}