我如何摆脱斯卡拉循环? [英] How do I break out of a loop in Scala?

查看:160
本文介绍了我如何摆脱斯卡拉循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  var large = 0 
for(i <-999 to 1乘以-1){
(j< -i到1 by -1){
val product = i * j
如果(最大>乘积)
// I如果(product.toString.equals(product.toString.reverse))
最大=最大最大产品
}



$ b

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



从2009年FOSDEM上的Scala Talk开始 http://www.slideshare.net/Odersky/ fosdem-2009-1013261 第22页的



暂停并继续
Scala不拥有他们。为什么?
他们有点必要;更好地使用许多较小的函数
问题如何与闭包进行交互。
他们是不需要的!

解释是什么?



假设你想总和数字,直到总数(i < - 0到1000)sum

  var sum = 0 
除非你想停止当(总和> 1000)。

$ b


$ b

该怎么办?有几种选择。
$ b $(1a)使用一些包含您测试的条件的构造。

<$ p $ (=> sum< code)> var sum = 0
(0-1000).iterator.takeWhile (警告 - 这取决于在评估过程中takeWhile测试和foreach是如何交错的细节,而且可能不应该是这样的。)

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

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

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

  var sum = 0 $ b $ (i< = 1000&& sum< = 1000){sum + = 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+中,这已经预先打包在<





$ b c $ c> scala.util.control.Breaks
使用的语法看起来很像您从C / Java中熟悉的旧的中断:

  import scala.util.control.Breaks._ 
var sum = 0
breakable {for(i < - 0 to 1000){
sum + =如果(总和> = 1000)中断
}}

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

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

太容易了,至少有三个我能想到的理由。首先,在大的代码块中,很容易忽略继续和中断语句,或者认为自己比真实的要多或少,或者需要打破两个你不能做的循环很容易 - 所以标准的使用,虽然方便,有其问题,因此你应该尝试以不同的方式来构建你的代码。其次,斯卡拉有各种各样的嵌套,你可能根本没有注意到,所以如果你能摆脱这些事情,你可能会惊讶于代码流的结束(特别是关闭)。第三,Scala的大部分循环实际上并不是正常的循环 - 它们是方法调用,它们有自己的循环,或者它们是递归,可能实际上也可能不是一个循环 - 尽管它们 / em> looplike,很难想出一个一致的方法来知道什么休息应该做的。所以,要保持一致,更明智的做法是不要有任何休息。

注意:功能等同所有这些你返回 sum 的值,而不是改变它的位置。这些更加习惯斯卡拉。但是,逻辑保持不变。 ( return 变成 return x 等)。

How do I break out a loop?

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
    }
}

How do I turn nested for loops into tail recursion?

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

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!

What is the explanation?

解决方案

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

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

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

What to do? There are several options.

(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)

(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) 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) Fall back to using a while loop

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

(2) Throw an exception.

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

(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) 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

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.

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.).

这篇关于我如何摆脱斯卡拉循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆