我们什么时候不应该在scala中使用“for loops”?

时间:2014-08-26 18:13:30

标签: scala

Twitter'} Effective Scala说:

" for为循环和聚合提供简洁和自然的表达。在展平许多序列时尤其有用。 for的语法在分配和分派闭包时掩盖了底层机制。这可能导致意外的成本和语义;例如

for (item <- container) {
  if (item != 2) 
    return
}
如果容器延迟计算,

可能会导致运行时错误,使得返回非局部!

由于这些原因,通常最好直接调用foreach,flatMap,map和filter - 但在澄清时使用fors。&#34;

我不明白为什么会出现运行时错误。

2 个答案:

答案 0 :(得分:1)

Twitter手册警告for内的代码可能绑定在闭包中,这是(在这种情况下)在执行环境内运行的函数用于捕获呼叫站点上存在的本地环境。您可以在此处详细了解闭包 - http://en.wikipedia.org/wiki/Closure_%28computer_programming%29

因此for构造可以将循环中的所有代码打包成一个单独的函数,将特定的item和本地环境绑定到闭包(以便所有对变量的引用都可以循环在函数内仍然有效),然后在其他地方执行该函数,即在另一个隐藏的调用框架中执行。

这会成为return的问题,它应该立即退出当前的调用帧。但是如果你的闭包在其他地方执行,那么闭包函数就成了返回的目标,而不是实际的周围方法,这就是你的意思。

答案 1 :(得分:1)

西蒙对回归问题有一个很好的答案。我想补充一点,一般情况下使用for循环只是在foreachmap等时会出现糟糕的Scala样式。例外情况是你想要嵌套的foreachmap等行为,在这种情况下是一个for循环,而不是特定的,一个&#34;用于理解&#34;是合适的。

E.g。

// Good, better than for loop
myList.foreach(println)

// Ok but might be easier to understsnd the for comprehension
(1 to N).map(i => (1 to M).map((i, _)))

// Equivilent to above and some say easier to read
for {
  i <- (1 to N)
  j <- (1 to M)
} yield (i, j)