1

为什么for {i <- (1 to 1000000000)} println(i)会给我 OutOfMemoryError 但(1 to 1000000000) foreach println没有?如果我必须使用 for-loop 语法,我该怎么办?

4

1 回答 1

2

这两个片段几乎是等价的。for编译器将 scala 中的语法脱糖到foreach, flatmap,withFilter以及map(如果你使用yield) 的应用程序中。此信息可在scala 语言规范的第 6.19 节中找到。

这意味着for循环

for (i <- 1 to 1000000000) println(i)

变成脱糖

(1 to 1000000000).foreach { case i => println(i) }

这几乎相当于

(1 to 1000000000) foreach println

这两个片段都不应导致 OutOfMemoryError。您可以查看源代码中foreachfor的覆盖定义:Range

https://github.com/scala/scala/blob/v2.10.1/src/library/scala/collection/immutable/Range.scala#L135

只有 1 个索引变量在处理循环时发生了变异。

但是确认索引 int 没有额外的装箱/拆箱很有用。事实证明,没有,尽管两种形式的堆栈跟踪略有不同:

Predef$.println(Object) line: 287
ForTest$$anonfun$f$1.apply$mcVI$sp(Int) line: 5
Range.foreach$mVc$sp(Function1) line: 141
ForTest$.f() line: 5

Predef$.println(Object) line: 287
ForTest$$anonfun$g$1.apply(Object) line: 6
ForTest$$anonfun$g$1.apply(Object) line: 6  // boxing here
Function1$class.apply$mcVI$sp(Function1, Int) line: 39
AbstractFunction1.apply$mcVI$sp(Int) line: 12
Range.foreach$mVc$sp(Function1) line: 141
ForTest$.g() line: 6
于 2013-04-27T10:46:32.077 回答