Built-in Control Structures
1 For expression
val filesHere = (new java.io.File(".")).listFiles
for (file <- filesHere)
println(file)
With the file <- filesHere syntax, which is called a generator. we iterate through the elements of filesHere.
// 结果是 1 2 3 4
for (i <- 1 to 4)
println("Iteration " + i)
// 结果是 1 2 3
for (i <- 1 until 4)
println("Iteration " + i)
1.1 Filtering
val filesHere = (new java.io.File(".")).listFiles
for (file <- filesHere if file.getName.endsWith(".scala"))
println(file)
for (
file <- filesHere
if file.isFile
if file.getName.endsWith(".scala")
) println(file)
1.2 Nested iteration
If you add multiple <- clauses, you will get nested "loops".
def fileLines(file: java.io.File) =
scala.io.Source.fromFile(file).getLines().toList
def grep(pattern: String) =
for (
file <- filesHere
if file.getName.endsWith(".scala");
line <- fileLines(file)
if line.trim.matches(pattern)
) println(file + ": " + line.trim)
grep(".*gcd.*")
1.3 Mid-stream variable bindings
def grep(pattern: String) =
for (
file <- filesHere
if file.getName.endsWith(".scala");
line <- fileLines(file)
trimmed = line.trim
if trimmed.matches(pattern)
) println(file + ": " + trimmed)
grep(".*gcd.*")
1.4 Producing a new collection
def scalaFiles =
for {
file <- filesHere
if file.getName.endsWith(".scala")
} yield file
Transforming an Array[File] to Array[Int] with a for:
val forLineLengths =
for {
file <- filesHere
if file.getName.endsWith(".scala")
line <- fileLines(file)
trimmed = line.trim
if trimmed.matches(".*for.*")
} yield trimmed.length
2 Exception Handling with Try Expressions
var half =
if (n % 2 == 0)
n / 2
else
throw new RuntimeException("n must be even")
2.1 Catching exceptions
import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException
try {
val f = new FileReader("input.txt")
// Use and close file
} catch {
case ex: FileNotFoundException => // Handle missing file
case ex: IOException => // Handle other I/O error
}
Note:
One different you'll quickly notice in Scala is that, unlike Java, Scala does not require you to catch checked exceptions or declare them in a throws clause. You can declare a throws if you wish with the @throwsannotation, but it is not required.
2.2 The finally clause
import java.io.FileReader
val file = new FileReader("input.txt")
try {
// Use the file
} finally {
file.close() // Be sure to close the file
}
3 Match Expressions
val firstArg = if (args.length > 0) args(0) else ""
firstArg match {
case "salt" => pritnln("pepper")
case "chips" => println("salsa")
case _ => println("huh?")
}
4 Living Without break and continue
You may have noticed that there has been no mention of break or continue. Scala leaves out these commands because they do not mesh well with function literals.
If you still feel the need to use break, there's help in Scala's standard library:
import scala.util.control.Breaks._
val in = new BufferedReader(new InputStreamReader(System.in))
breakble {
while (true) {
println("? ")
if (in.readLine() == "") break
}
}
5 Variable Scope
val a = 1;
{
val a = 2; // Compiles just fine
println(a)
}
println(a)