为什么Scala中的元组不能遍历?
Why can't tuples in Scala be traversed?
假设我创建一个 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
不应该以同样的方式工作吗?
归结为类型。
您希望 _<position>
等动态访问器具有什么类型?在一般情况下,唯一有效的是 Any
。在像 Scala 这样的强类型语言中,这对于大多数用途来说是无用的。
好消息是问题 可以 以类型安全的方式处理 - 参见例如HList
-style tuple handling in shapeless.
但是,标准 Scala 库中没有这样的机制(除非使用宏等繁重的元编程)。
对于元组,有一个 productIterator
方法可以让您有机会迭代元组的元素。但显然,这种迭代的每个元素都是 Any
类型
您可以提供一个 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)
}
你必须为你需要一个元组的每个元数编写(或生成)这个。
I understand that it is clearly stated that Tuples are not iterable, but if ._1
works , shouldn't ._i
work the same way ?
为什么要这样做?在一种情况下,您正在调用方法 _1
(确实存在),在另一种情况下,您正在调用方法 _i
(不存在)。调用两种不同的方法通常 not "work the same way",尤其是当其中之一甚至不存在时。
假设我创建一个 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
不应该以同样的方式工作吗?
归结为类型。
您希望 _<position>
等动态访问器具有什么类型?在一般情况下,唯一有效的是 Any
。在像 Scala 这样的强类型语言中,这对于大多数用途来说是无用的。
好消息是问题 可以 以类型安全的方式处理 - 参见例如HList
-style tuple handling in shapeless.
但是,标准 Scala 库中没有这样的机制(除非使用宏等繁重的元编程)。
对于元组,有一个 productIterator
方法可以让您有机会迭代元组的元素。但显然,这种迭代的每个元素都是 Any
您可以提供一个 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)
}
你必须为你需要一个元组的每个元数编写(或生成)这个。
I understand that it is clearly stated that Tuples are not iterable, but if
._1
works , shouldn't._i
work the same way ?
为什么要这样做?在一种情况下,您正在调用方法 _1
(确实存在),在另一种情况下,您正在调用方法 _i
(不存在)。调用两种不同的方法通常 not "work the same way",尤其是当其中之一甚至不存在时。