在Scala集合中,如果要迭代一个集合(不返回结果,即在集合的每个元素上执行副作用),可以通过以下两种方式之一实现:
或
考虑到我可以忽略map输出的内容,我想不出为什么需要存在和使用两种不同的方法,因为map似乎包含了foreach的所有功能。实际上,如果一个智能编译器和虚拟机没有将集合对象创建优化掉,即使它没有被分配给任何变量、读取或在任何地方使用,我也会印象深刻。
因此,问题是:我对吗?在代码中没有理由调用foreach吗?
注意:
(*) 惰性映射的概念,正如这个问题详细说明的那样,可能会改变一些事情,并且有理由使用foreach,但据我所见,需要特别遇到LazyMap,而正常
(**) 如果不是“使用”集合,而是“编写”集合,那么很快就会发现for推导语法实际上是一个语法糖,生成"foreach"调用,即这两行代码生成完全等效的代码:
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输出的内容,我想不出为什么需要存在和使用两种不同的方法,因为map似乎包含了foreach的所有功能。实际上,如果一个智能编译器和虚拟机没有将集合对象创建优化掉,即使它没有被分配给任何变量、读取或在任何地方使用,我也会印象深刻。
因此,问题是:我对吗?在代码中没有理由调用foreach吗?
注意:
(*) 惰性映射的概念,正如这个问题详细说明的那样,可能会改变一些事情,并且有理由使用foreach,但据我所见,需要特别遇到LazyMap,而正常
(**) 如果不是“使用”集合,而是“编写”集合,那么很快就会发现for推导语法实际上是一个语法糖,生成"foreach"调用,即这两行代码生成完全等效的代码:
for (element <- myCollection) { doStuffWithElement(element); }
myCollection.foreach { element => doStuffWithElement(element); }
因此,如果一个人在意其他人使用该集合类与for
语法,那么他可能仍然希望实现foreach
方法。
foreach
而不是map
可以很好地区分有副作用和无副作用的函数,这样做很好。我并不关心编译器是否对它们进行了优化。不同之处可以更清楚地表达代码的目的。 - Michael Zajacfor ..
(不带 yield)而不是直接使用.foreach
,因为它进一步(对我来说)显示了迭代的副作用和序列转换之间的区别。此外,假设被迭代的序列不是惰性的可能是危险的。 - user2864740map
еҲ°foreach
д»Јз ҒпјҢйӮЈд№ҲжҲ‘дјҡйқһеёёеҚ°иұЎж·ұеҲ»гҖӮиҝҷеҜ№жҲ‘жқҘиҜҙжҳҜдёҖдёӘжһҒе…¶дёҚе№іеҮЎзҡ„дјҳеҢ–гҖӮ - ziggystar