开发者

Skipping to the beginning of a for loop in a Scala program

In a for loop in my Scala code, i want to skip to the beginning of the loop and not execute 开发者_JS百科following statements if a particular condition is true. In Java i can use 'continue' for doing this. But 'continue' does not seem to work in Scala. So how can i skip to the beginning of my loop in a Scala program ?

Please Help Thank You.


First, your best option is usually to avoid that sort of construct anyway, and try to use higher-level methods instead (e.g. you can often do xs.map(doSomeStuff).filter(condition).foreach(doConditionalStuff)). This isn't always practical, but it is far more often than you might initially suspect. Still, the issue remains for those cases where continue is useful: a very long series of guards within a long code block that cannot be logically broken into pieces.

continue is a difficult language construct for a language with anonymous functions. One reason is practical: the anonymous function is a function, and you can't easily go back to some loop that's calling it just by executing a jump. Another reason is conceptual: if you're in a map method, which itself is a kind of loop, where exactly should the continue take you back to the beginning of?

Rather than dealing with these awkward cases, Scala provides (as a library function, based upon exceptions) a breakable construct that explicitly specifies where you want to break to:

import scala.util.control.Breaks._
breakable {
  for (i <- 1 to 10) {
    if (i>3) break
    println(i)
  }
}

But because this is a generic construct, you can use it inside the for loop also:

import scala.util.control.Breaks._
for (i <- 1 to 10) {
  breakable {
    if ((i%2)==0) break
    println(i)
  }
}

You can even break to multiple levels if you create your own break classes. Here's an example of simulating a for loop with both break and continue:

val outer,inner = new scala.util.control.Breaks
outer.breakable {
  for (i <- 1 to 10) {
    inner.breakable {
      if ((i%2)==0) inner.break
      if (i>3) outer.break
      println(i)
    }
  }
}

And if you use this pattern a lot, you can change your imports to make it nicer:

// Do this once at the top of the file
import scala.util.control.Breaks._
object Continued extends scala.util.control.Breaks {}
import Continued.{break=>continue, breakable=>continuing}

// Now every time you need it:
breakable{ for (i <- 1 to 10) continuing {
  if ((i%2)==0) continue
  if (i>3) break
  println(i)
}}

It is a bit more work to type if you really need that functionality, but given how nonsensical breaks and continues are in the context of the other very useful functionality that Scala has, it's not a bad compromise.


If you're using Scala 2.7, from http://www.scala-lang.org/node/257

These keywords are not included in Scala 2.7, and must be implemented in a different way. For break, the simplest thing to do is to divide your code into smaller methods and use the return to exit early. For continue, a simple approach is to place the skipped-over parts of a loop into an if. Scala 2.8 will include break, but not continue.

If you're using Scala 2.8

import util.control.Breaks._
// for continue, write this somewhere in your program
val continue = new Breaks
/* use like */
Breaks.breakable {
  for (i <- 1 to 10)
  continue.breakable { if (i % 2 == 0) continue.break; println(i); if (i == 7) Breaks.break }
}


//source http://daily-scala.blogspot.com/2010/04/breaks.html

Note that normally needing break and continue means that you aren't being as functional as Scala would like you to be.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜