现在,我花了一会儿 找出为什么我的递归以某种方式设法炸毁堆栈。这是导致此问题的部分:
scala> for {
| i <- List(1, 2, 3)
| j = { println("why am I evaluated?"); 10 } if false
| } yield (i, j)
why am I evaluated?
why am I evaluated?
why am I evaluated?
res0: List[(Int, Int)] = List()
这不是很疯狂吗?为什么要评价
j = ...
如果它以 if false
结尾等会从不 使用?代替
{ println ... }
时会发生什么你有一个递归调用(和递归保护而不是 if false
),我知道。 :<为什么?!
最佳答案
我要出去说接受的答案可以说更多。
这是一个解析器错误。
守卫可以立即跟随一个生成器,否则是 semi
是必需的(实际的或推断的)。
Here is the syntax.
下面是 res4
的行不应该编译。
scala> for (i <- (1 to 5).toList ; j = 2 * i if j > 4) yield j
res4: List[Int] = List(6, 8, 10)
scala> for (i <- (1 to 5).toList ; j = 2 * i ; if j > 4) yield j
res5: List[Int] = List(6, 8, 10)
发生的情况是 j 的 val def 与 i 生成器合并以形成一个新的生成器对
(i,j)
.然后守卫看起来就像它只是跟随(合成)生成器。但是语法仍然是错误的。语法是我们的 friend !早在类型系统出现之前,它就是我们的 BFF。
在线咨询
res5
,很明显,后卫没有保护 val def。更新:
实现错误已降级(或升级,取决于您的观点)为 specification bug .
检查这种用法,如果控制前面的 valdef,守卫看起来像尾随,就像在 Perl 中一样,属于您最喜欢的样式检查器的范围。
关于scala - 在 Scala 中用于理解性评估的奇怪 (?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19599947/