您有三个(左右)选项可以跳出循环。
假设您想对数字求和,直到总数大于 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 += 1; 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 的大多数“循环”实际上并不是普通的循环——它们是有自己循环的方法调用,looplike,很难想出一个一致的方法来知道“break”之类的应该做什么。因此,为了保持一致,更明智的做法是根本不“休息”。
注意:所有这些都有功能等价物,您可以在其中返回值sum
而不是对其进行变异。这些是更惯用的Scala。但是,逻辑保持不变。(return
变成return x
等)。