【发布时间】:2013-03-13 17:16:06
【问题描述】:
所以我花了几个小时试图弄清楚这段代码是如何产生素数的。
lazy val ps: Stream[Int] = 2 #:: Stream.from(3).filter(i =>
ps.takeWhile{j => j * j <= i}.forall{ k => i % k > 0});
我使用了许多 printlns 等,但没有什么能让它更清晰。
这就是我认为代码的作用:
/**
* [2,3]
*
* takeWhile 2*2 <= 3
* takeWhile 2*2 <= 4 found match
* (4 % [2,3] > 1) return false.
* takeWhile 2*2 <= 5 found match
* (5 % [2,3] > 1) return true
* Add 5 to the list
* takeWhile 2*2 <= 6 found match
* (6 % [2,3,5] > 1) return false
* takeWhile 2*2 <= 7
* (7 % [2,3,5] > 1) return true
* Add 7 to the list
*/
但如果我将列表中的 j*j 更改为 2*2,我假设会完全一样,它会导致 stackoverflow 错误。
我显然在这里遗漏了一些基本的东西,并且真的可以像我五岁一样向我解释这一点。
任何帮助将不胜感激。
【问题讨论】:
-
为什么要使用“懒惰”?初始化 Stream 不需要太多时间或内存,而且在
ps不偷懒的情况下也能正常工作,对吧? -
@AmigoNico mmlac 在对我的回答的评论中引起了我的注意——
lazy实际上可能是必要的,因为val具有递归定义。奇怪的是,在我自己在 Scala 2.10.4 中进行的测试中,lazy在 REPL 中不需要,但在普通代码中却是必需的——可能是 REPL 错误。 -
啊,当然可以。我应该仔细看看。