sma*_*c89 2 stack-overflow primes scala operator-precedence lazy-sequences
有人可以帮我理解这里发生了什么.我有这个定义来生成素数:
def primes: Stream[Long] = {
2 #:: 3 #:: 5 #:: 7 #::Stream.iterate(11L)(_ + 2).filter {
n => primes takeWhile (p => p*p <= n) forall (n % _ != 0)
}
}
Run Code Online (Sandbox Code Playgroud)
def primes: Stream[Long] = {
2 #:: 3 #:: 5 #:: 7 #::Stream.iterate(11L)(_ + 2) filter {
n => primes takeWhile (p => p*p <= n) forall (n % _ != 0)
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,两个定义完全相似,除了第二个定义没有.前过滤器,而第一个定义具有前置过滤器.
问题是运行第一个,按预期运行并给我们素数,但第二个产生一个java.lang.StackOverflowError.有人可以对此有所了解吗?在任何一种情况下,传递给过滤器的是什么?
Scala版本:2.11.6
Java版本:1.8.0_121
这是我用来测试每个程序的完整程序:
object Main {
def primes: Stream[Long] = {
2 #:: 3 #:: 5 #:: 7 #::Stream.iterate(11L)(_ + 2) filter {
n => primes takeWhile (_ <= sqrt(n)) forall (n % _ != 0)
}
}
def primes2: Stream[Long] = {
2 #:: 3 #:: 5 #:: 7 #::Stream.iterate(11L)(_ + 2).filter {
n => primes2 takeWhile (p => p*p <= n) forall (n % _ != 0)
}
}
def main(args: Array[String]): Unit = {
println(primes.take(args.head.toInt).force)
}
}
Run Code Online (Sandbox Code Playgroud)
没有的表示法.具有与任何自定义中缀相同的优先级.所以第一个仅适用filter于Stream.iterate(11L)(_ + 2)- 第二个适用于2 #:: 3 #:: 5 #:: 7 #::Stream.iterate(11L)(_ + 2).
第一个工作的原因是元素2,3,5和7 primes在过滤器运行时已经存在,因此当过滤器尝试使用时primes,这些元素已经在其中.
在第二个代码中并非如此,因为过滤器也应用于这些元素,这意味着primes在过滤器为它们返回true之前它们不会出现.但是过滤器需要在返回任何内容之前从prime中获取元素,因此在尝试获取元素时它会在无限递归中丢失.
| 归档时间: |
|
| 查看次数: |
270 次 |
| 最近记录: |