scala - 如何跳出 Scala 中的循环?

标签 scala for-loop break tail-recursion

如何打破循环?

var largest=0
for(i<-999 to 1 by -1) {
    for (j<-i to 1 by -1) {
        val product=i*j
        if (largest>product)
            // I want to break out here
        else
           if(product.toString.equals(product.toString.reverse))
              largest=largest max product
    }
}

如何将嵌套的 for 循环转变为尾递归?

来自 FOSDEM 2009 的 Scala 演讲 http://www.slideshare.net/Odersky/fosdem-2009-1013261 第 22 页:

Break and continue Scala does not have them. Why? They are a bit imperative; better use many smaller functions Issue how to interact with closures. They are not needed!

解释是什么?

最佳答案

您有三个(左右)选项来打破循环。

假设您想要对数字进行求和,直到总数大于 1000。您尝试一下

var sum = 0
for (i <- 0 to 1000) sum += i

除非您想在(总和 > 1000)时停止。

该怎么办?有多种选择。

(1a) 使用一些包含您测试的条件的构造。

var sum = 0
(0 to 1000).iterator.takeWhile(_ => sum < 1000).foreach(i => sum+=i)

(警告 - 这取决于 takeWhile 测试和 foreach 在评估期间如何交错的详细信息,并且可能不应该在实践中使用!)。

(1b) 使用尾递归代替 for 循环,充分利用在 Scala 中编写新方法的简便性:

var sum = 0
def addTo(i: Int, max: Int) {
  sum += i; if (sum < max) addTo(i+1,max)
}
addTo(0,1000)

(1c) 重新使用 while 循环

var sum = 0
var i = 0
while (i <= 1000 && sum <= 1000) { sum += i; i += 1 }

(2) 抛出异常。

object AllDone extends Exception { }
var sum = 0
try {
  for (i <- 0 to 1000) { sum += i; if (sum>=1000) throw AllDone }
} catch {
  case AllDone =>
}

(2a) 在 Scala 2.8+ 中,这已经预先打包在 scala.util.control.Breaks 中,使用的语法看起来很像您熟悉的 C/Java 中的旧中断:

import scala.util.control.Breaks._
var sum = 0
breakable { for (i <- 0 to 1000) {
  sum += i
  if (sum >= 1000) break
} }

(3) 将代码放入方法中并使用return。

var sum = 0
def findSum { for (i <- 0 to 1000) { sum += i; if (sum>=1000) return } }
findSum

出于我能想到的至少三个原因,故意让这变得不太容易。首先,在大型代码块中,很容易忽略“继续”和“中断”语句,或者认为您打破了比实际情况更多或更少的情况,或者需要打破两个您无法做到的循环无论如何都很容易——所以标准用法虽然方便,但也有其问题,因此您应该尝试以不同的方式构建代码。其次,Scala 具有您可能根本没有注意到的各种嵌套,因此,如果您能够摆脱困境,您可能会对代码流程的最终结果感到惊讶(尤其是闭包)。第三,大多数 Scala 的“循环”实际上并不是普通的循环——它们是有自己的循环的方法调用,或者它们是递归,实际上可能是也可能不是循环——尽管它们起作用 就像循环一样,很难想出一个一致的方法来知道“break”等应该做什么。因此,为了保持一致,更明智的做法是根本不“休息”。

注意:所有这些都有等价的功能,您可以返回 sum 的值,而不是就地改变它。这些是更惯用的 Scala。然而,逻辑仍然是一样的。 (return 变为 return x 等)。

关于scala - 如何跳出 Scala 中的循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2742719/

相关文章:

c - 如何计算这个函数的复杂度?

PHP:默认情况切换中断?

scala - 事件应该在外部可变吗?

java - Spark SQL - 转换列时出现 java.lang.UnsupportedOperationException : empty. init

Python 字典键顺序与推导式

c# - 为什么在 switch 语句中 yield return 之后需要 break?

loops - GNU Smalltalk - 从 whileTrue 循环中断而不返回

scala - 循环直到 scala 中满足某个条件

scala - Scala中高级类型的类型约束

Java-按给定顺序迭代for循环