本文介绍了如何跳出 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 循环转换为尾递归?

How do I turn nested for loops into tail recursion?

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

From Scala Talk at FOSDEM 2009 http://www.slideshare.net/Odersky/fosdem-2009-1013261on the 22nd page:

中断并继续Scala 没有它们.为什么?它们有点势在必行;更好地使用许多较小的功能问题如何与闭包交互.他们不需要!

解释是什么?

推荐答案

您有三个(左右)选项可以跳出循环.

You have three (or so) options to break out of loops.

假设你想对数字求和,直到总数大于 1000.你试试

Suppose you want to sum numbers until the total is greater than 1000. You try

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

除非您想在 (sum > 1000) 时停止.

except you want to stop when (sum > 1000).

怎么办?有多种选择.

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

(1a) Use some construct that includes a conditional that you test.

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

(警告——这取决于 takeWhile 测试和 foreach 在评估过程中如何交错的细节,可能不应该在实践中使用!).

(warning--this depends on details of how the takeWhile test and the foreach are interleaved during evaluation, and probably shouldn't be used in practice!).

(1b) 使用尾递归而不是 for 循环,利用在 Scala 中编写新方法是多么容易:

(1b) Use tail recursion instead of a for loop, taking advantage of how easy it is to write a new method in Scala:

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

(1c) 回退到使用 while 循环

(1c) Fall back to using a while loop

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 旧突破:

(2a) In Scala 2.8+ this is already pre-packaged in scala.util.control.Breaks using syntax that looks a lot like your familiar old break from C/Java:

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

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

(3) Put the code into a method and use return.

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

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

This is intentionally made not-too-easy for at least three reasons I can think of. First, in large code blocks, it's easy to overlook "continue" and "break" statements, or to think you're breaking out of more or less than you really are, or to need to break two loops which you can't do easily anyway--so the standard usage, while handy, has its problems, and thus you should try to structure your code a different way. Second, Scala has all sorts of nestings that you probably don't even notice, so if you could break out of things, you'd probably be surprised by where the code flow ended up (especially with closures). Third, most of Scala's "loops" aren't actually normal loops--they're method calls that have their own loop, or they are recursion which may or may not actually be a loop--and although they act looplike, it's hard to come up with a consistent way to know what "break" and the like should do. So, to be consistent, the wiser thing to do is not to have a "break" at all.

注意:所有这些都有等价的功能,您可以在其中返回 sum 的值,而不是原地改变它.这些是更惯用的 Scala.但是,逻辑保持不变.(return 变成 return x 等).

Note: There are functional equivalents of all of these where you return the value of sum rather than mutate it in place. These are more idiomatic Scala. However, the logic remains the same. (return becomes return x, etc.).

这篇关于如何跳出 Scala 中的循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 15:30