我如何摆脱Scala循环?
我如何打破循环?
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循环转换为尾递归?
从FPSDEM 2009的斯卡拉谈话http://www.slideshare.net/Odersky/fosdem-2009-1013261在第22页:
打破并继续斯卡拉没有他们。 为什么? 他们有点必要; 更好地使用许多较小的函数发布如何与闭包进行交互。 他们不需要!
什么是解释?
你有三个(或多个)选项来打破循环。
假设你想总和数字,直到总数大于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的大多数“循环”实际上并不是正常循环 - 它们是方法调用,它们有自己的循环,或者它们是递归,可能实际上可能不是循环 - 尽管它们循环操作,但很难想出一个一致的方法来知道什么“突破”等应该做的。 所以,要保持一致,更明智的做法是不要有“休息”。
注意 :所有这些功能都等同于您返回sum
的值,而不是将其改变。 这些更具惯用斯卡拉。 但是,逻辑保持不变。 ( return
成为return x
等)。
这已经改变了Scala 2.8,它有一个使用中断的机制。 您现在可以执行以下操作:
import scala.util.control.Breaks._
var largest = 0
// pass a function to the breakable method
breakable {
for (i<-999 to 1 by -1; j <- i to 1 by -1) {
val product = i * j
if (largest > product) {
break // BREAK!!
}
else if (product.toString.equals(product.toString.reverse)) {
largest = largest max product
}
}
}
打破for循环永远不是一个好主意。 如果您使用for循环,则意味着您知道要迭代多少次。 使用2个条件的while循环。
例如
var done = false
while (i <= length && !done) {
if (i > 1000) {
done = true;
}
链接地址: http://www.djcxy.com/p/80565.html