Scala:为什么zipped方法成功地处理了列表的元组而不可遍历?
我试图在Scala中将两个可遍历项压缩在一起。以下示例使用List而不是Traversable实现了我想要的功能:Scala:为什么zipped方法成功地处理了列表的元组而不可遍历?,scala,Scala,我试图在Scala中将两个可遍历项压缩在一起。以下示例使用List而不是Traversable实现了我想要的功能: (List(1,2,3), List(3,4,5)).zipped.foreach( (a,b) => println(a,b) ) (Traversable(1,2,3), Traversable(3,4,5)).zipped.foreach( (a,b) => println(a,b) ) (Traversable(1,2,3), Traversable(3,4
(List(1,2,3), List(3,4,5)).zipped.foreach( (a,b) => println(a,b) )
(Traversable(1,2,3), Traversable(3,4,5)).zipped.foreach( (a,b) => println(a,b) )
(Traversable(1,2,3), Traversable(3,4,5).toIterable).zipped.foreach( (a,b) => println(a,b) )
此代码打印:
(1,3)
(2,4)
(3,5)
但是,当我尝试使用Traversable执行此操作时:
(List(1,2,3), List(3,4,5)).zipped.foreach( (a,b) => println(a,b) )
(Traversable(1,2,3), Traversable(3,4,5)).zipped.foreach( (a,b) => println(a,b) )
(Traversable(1,2,3), Traversable(3,4,5).toIterable).zipped.foreach( (a,b) => println(a,b) )
我得到以下错误:
8: error:
No implicit view available from
Traversable[Int] => scala.collection.IterableLike[El2,Repr2].
有人能解释一下上面的错误是怎么回事吗?什么是视图?如何实现它想要的隐式视图?我已经忘记了为什么Traversable比Iterable更普遍——也许这与并行集合有关,也许他们说这是一个错误,或者是一个难题 但你可以:
scala> (Traversable(1,2,3), Traversable(3,4,5).toIterable).zipped.foreach( (a,b) => println(a,b) )
(1,3)
(2,4)
(3,5)
补充问题是,引入一种隐式的方法来为您这样做是否有不利之处
编辑:要回答您的问题,我想应该是这样的,但这不是一个建议:
scala> implicit def `convert it`[A](t: Traversable[A]): Iterable[A] = t.toIterable
warning: there were 1 feature warning(s); re-run with -feature for details
convert$u0020it: [A](t: Traversable[A])Iterable[A]
scala> (Traversable(1,2,3), Traversable(3,4,5)).zipped.foreach( (a,b) => println(a,b) )
(1,3)
(2,4)
(3,5)
从这个意义上说,“视图”是一个转换函数,它允许您将可遍历对象作为一个可遍历对象进行“查看”,而不一定与“集合视图”有关
更新:
查看源代码,并且只有第二个集合必须是可编辑的
原因是Tuple2Zipped
将只foreach
-遍历第一个集合,但迭代第二个集合,以便在时停止!hasNext
有一个有趣的老话题,比如:
例如,样本抽取报价:
至少在可遍历的契约中隐含的是您可以
多次遍历它
公共接口的最佳规则是在
你可以。如果需要,您可以随时将其转换为am迭代器
还有一个问题,我认为最有利于开怀大笑,尽管这是真的。如果你看看这个问题,你会发现它看起来是这样的:
def zipped[El1, Repr1, El2, Repr2](implicit w1: (T1) ⇒ TraversableLike[El1, Repr1], w2: (T2) ⇒ IterableLike[El2, Repr2]): Tuple2Zipped[El1, Repr1, El2, Repr2]
这意味着该函数采用两个隐式转换器:
将元组(T1)中第一个元素的类型转换为TraversableLikew1:(T1)⇒ TraversableLike[El1,Repr1]
将第二个元素(T2)的类型转换为IterableLikew2:(T2)⇒ IterableLike[El2,Repr2]
(List(1,2,3), List(3,4,5)).zipped.foreach( (a,b) => println(a,b) )
(Traversable(1,2,3), Traversable(3,4,5)).zipped.foreach( (a,b) => println(a,b) )
(Traversable(1,2,3), Traversable(3,4,5).toIterable).zipped.foreach( (a,b) => println(a,b) )
谢谢,我想我的问题可以归结为遍历和iterable之间的区别,以及仅仅转换为iterable是否有任何缺点。第一个示例没有缺点。在某个时刻,您需要一个迭代器。我会编辑的。谢谢,这很清楚,尽管我仍然不明白为什么第二个元素需要是iterable。我知道它需要它,因为签名是这样说的,但是有可能在两个可遍历对象上实现zip操作吗?有什么理由这样做吗?@joshuaar原因是
Tuple2Zipped
将只foreach
-遍历第一个集合,但迭代第二个集合,以便在时停止!hasNext
。是的,没错。你可以查看所有的细节。明白了,现在一切都有意义了。谢谢你的链接。