内建控制结构
1.嵌套枚举
如果加入多个<-子句,你就得到了嵌套的“循环”。
如果愿意的话,你可以使用大括号代替小括号环绕发生器和过滤器。使用大括号的一个好处是你可以省略一些使用小括号必须加的分号。
外层的循环枚举 filesHere,内层的枚举所有以.scala 结尾文件的 fileLines(file)。
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.*")
2.使用try表达式处理异常
Scala 的异常和许多其它语言的一样。代之用普通方式那样返回一个值,方法可以通过抛出一个异常中止。方法的调用者要么可以捕获并处理这个异常,或者也可以简单地中止掉,并把异常升级到调用者的调用者。异常可以就这么升级,一层层释放调用堆栈,直到某个方法处理了它或没有剩下其它的方法。
异常的抛出看上去与 Java 的一模一样。首先创建一个异常对象然后用 throw 关键字抛出:
throw new IllegalArgumentException
3.捕获异常
选择 catch 子句这样的语法的原因是为了与 Scala 很重要的部分:模式匹配:pattern matching 保持一致。
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
}
如果异常是 FileNotFoundException,那么第一个子句将被执行。如果是 IOException 类型,第二个子句将被执行。如果都不是,那么 try-catch 将终结并把异常上升出去。
4.finally子句
如果想让某些代码无论方法如何中止都要执行的话,可以把表达式放在 finally 子句里。如,你或许想让打开的文件即使是方法抛出异常退出也要确保被关闭 。
import java.io.FileReader
val file = openFile()
try {
// 使用文件
} <span style="font-family: SimSun; font-size: 10pt;">finally {</span>
file.close() // 确保关闭文件
}
5.生成值
能够产生值的 catch 子句
import java.net.URL
import java.net.MalformedURLException
def urlFor(path: String) =
try {
new URL(path)
} catch {
case e: MalformedURLException =>
new URL("http://www.scalalang.org")
}
6.match表达式
Scala 的匹配表达式允许你在许多可选项:alternative 中做选择,就好象其它语言中的 switch语句。通常说来 match 表达式可以让你使用任意的模式:pattern 做选择,第十五章会介绍。通用的模式可以稍等再说。目前,只要考虑使用 match 在若干可选项中做选择。
缺省情况用下划线(_)说明,这是常用在 Scala 里作为占位符表示完全不清楚的值的通配符。
val firstArg = if (args.length > 0) args(0) else ""
firstArg match {
case "salt" => println("pepper")
case "chips" => println("salsa")
case "eggs" => println("bacon")
case _ => println("huh?")
}
7.离开break和continue
不用 var 做循环的递归替代方法,它用递归替代了循环。每个 continue 都被带有 i + 1 做参数的递归调用替换掉,有效地跳转到下一个整数。许多人都发现当他们开始使用递归后,这种编程风格更易于理解。
def searchFrom(i: Int): Int =
if (i >= args.length) -1// 不要越过最后一个参数
else if (args(i).startsWith("-")) searchFrom(i + 1)// 跳过选项 else if (args(i).endsWith(".scala")) i // 找到!
else searchFrom(i + 1) // 继续找
val i = searchFrom(0)