Scala:“map”vs“foreach” - 有没有理由在实践中使用“foreach”?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scala:“map”vs“foreach” - 有没有理由在实践中使用“foreach”?相关的知识,希望对你有一定的参考价值。
在Scala集合中,如果想要迭代一个集合(没有返回结果,即对集合的每个元素做一个副作用),它可以用
final def foreach(f: (A) ⇒ Unit): Unit
要么
final def map[B](f: (A) ⇒ B): SomeCollectionClass[B]
除了可能的延迟映射(*)之外,从最终用户的角度来看,我发现这些调用没有差异:
myCollection.foreach { element =>
doStuffWithElement(element);
}
myCollection.map { element =>
doStuffWithElement(element);
}
鉴于我可以忽略哪些地图输出。当map
似乎包含foreach
的所有功能时,我想不出为什么存在和使用两种不同方法的任何具体原因,事实上,如果智能编译器和VM不会给我留下深刻的印象优化出该集合对象的创建,因为它没有被分配给任何东西,或者在任何地方读取或使用。
所以,问题是 - 我是对的 - 并且没有理由在一个代码中的任何地方调用foreach
吗?
笔记:
(*)懒惰的映射概念,as throughly illustrated in this question,可能会改变一些事情,并证明使用foreach
,但据我所知,一个人特别需要偶然发现一个LazyMap
,正常
(**)如果一个人没有使用集合,而是写一个集合,那么很快就会发现for
理解语法语法实际上是生成“foreach”调用的语法糖这一事实,即这两行生成完全等效的代码:
for (element <- myCollection) { doStuffWithElement(element); }
myCollection.foreach { element => doStuffWithElement(element); }
因此,如果一个人关心使用for
语法的集合类的其他人,可能仍然想要实现foreach
方法。
答案
我可以想到几个动机:
- 当
foreach
是Unit
类型的方法的最后一行时,你的编译器不会发出警告,但会使用map
(你需要使用-Ywarn-value-discard
)。有时你使用warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
获得map
但不会使用foreach
。 - 一般可读性 - 如果使用
map
,读者可以知道您在不返回某些内容的情况下改变某些状态,但需要更多的认知资源来理解相同的操作 - 进一步1.您还可以在传递命名函数时进行类型检查,然后进入
map
和foreach
- 使用
foreach
不会构建新的列表,因此效率会更高(感谢@Vishnu)
另一答案
scala> (1 to 5).iterator map println
res0: Iterator[Unit] = non-empty iterator
scala> (1 to 5).iterator foreach println
1
2
3
4
5
另一答案
如果建造机械可以优化,我会留下深刻的印象。
scala> :pa
// Entering paste mode (ctrl-D to finish)
implicit val cbf = new collection.generic.CanBuildFrom[List[Int],Int,List[Int]] {
def apply() = new collection.mutable.Builder[Int, List[Int]] {
val b = new collection.mutable.ListBuffer[Int]
override def +=(i: Int) = { println(s"Adding $i") ; b +=(i) ; this }
override def clear() = () ; override def result() = b.result() }
def apply(from: List[Int]) = apply() }
// Exiting paste mode, now interpreting.
cbf: scala.collection.generic.CanBuildFrom[List[Int],Int,List[Int]] = $anon$2@e3cee7b
scala> List(1,2,3) map (_ + 1)
Adding 2
Adding 3
Adding 4
res1: List[Int] = List(2, 3, 4)
scala> List(1,2,3) foreach (_ + 1)
以上是关于Scala:“map”vs“foreach” - 有没有理由在实践中使用“foreach”?的主要内容,如果未能解决你的问题,请参考以下文章