scala内建的控制结构:if、while、for、try、match和函数调用,scala从语法层面支持函数字面量。
(1)if 表达式
// if检测条件并根据是否为真,执行两个分支中的一个
var filename = "default.txt"
if (!args.isEmpty)
filename = args(0)
//优化,根据条件做初始化
val filename =
if (!args.isEmpty) args(0)
else "default.txt"
val 和var:val不能再次赋值,var可以在它生命周期中被多次赋值。
(2)while循环
object Misc {
var loopcounter = 2
def ifVariations(args: Array[String]) {
println("args [" + args.toList + "]")
{
var filename = "default.txt"
if (!args.isEmpty)
filename = args(0)
println("filename [" + filename + "]")
}
{
val filename =
if (!args.isEmpty) args(0)
else "default.txt"
println("filename [" + filename + "]")
}
println(if (!args.isEmpty) args(0) else "default.txt")
}
//while 循环
def gcdLoop(x: Long, y: Long): Long = {
var a = x
var b = y
while (a != 0) {
val temp = a
a = b % a
b = temp
}
b
}
//使用递归计算最大公约数
def gcd(x: Long, y: Long): Long =
if (y == 0) x else gcd(y, x % y)
def whileLoop() {
def readLine() = {
if (loopcounter > 0) {
loopcounter -= 1
"a line"
} else
""
}
//do-while 循环
var line = ""
do {
line = readLine()
println("Read: "+ line)
} while (line != "")
}
def shadowing() {
val a = 1;
{
val a = 2 // Compiles just fine
println(a)
}
println(a)
}
def shadowing2() {
val a = 1;
{
val a = 2;
{
println(a)
}
}
}
}
Misc.ifVariations(Array("foo"))
Misc.ifVariations(Array())
println("gcdLoop(2, 4) [" + Misc.gcdLoop(2, 4) + "]")
println("gcdLoop(3, 4) [" + Misc.gcdLoop(3, 4) + "]")
println("gcd(2, 4) [" + Misc.gcd(2, 4) + "]")
println("gcd(3, 4) [" + Misc.gcd(3, 4) + "]")
Misc.whileLoop()
Misc.shadowing()
Misc.shadowing2()
(3)for表达式
object Files {
val filesHere = (new java.io.File(".")).listFiles
//枚举集合类
//列举文件中的列
def printFiles() {
for (file <- filesHere)
println(file)
}
def printFilesIter() {
// Not common in Scala...
for (i <- 0 to filesHere.length - 1)
println(filesHere(i))
}
//用带过滤器的for发现.scala文件
def printScalaFiles() {
val filesHere = (new java.io.File(".")).listFiles
for (file <- filesHere if file.getName.endsWith(".scala"))
println(file)
}
def printScalaFiles2() {
for (file <- filesHere)
if (file.getName.endsWith(".scala"))
println(file)
}
//在for表达式中使用多个过滤器
def printScalaFiles3() {
for (
file <- filesHere
if file.isFile;//如果有多个过滤器,if子句必须使用分号分隔
if file.getName.endsWith(".scala")
) println(file)
}
//嵌套循环
def fileLines(file: java.io.File) =
scala.io.Source.fromFile(file).getLines.toList
def grepParens(pattern: String) {
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(pattern)
}
def grepGcd() {
def grep(pattern: String) = grepParens(pattern)
grep(".*gcd.*")
}
def grepGcd2() {
//流间(mid-stream)变量绑定,绑定的变量(trimmed)作为val引入和使用,不过不带关键字val,trimmed变量从半路引入for表达式,初始化为line.trim的结果值。
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.*")
}
//制造新集合,创建一个值去记住每一次的迭代
//for{子句}yield{循环体},yield在整体循环之前。
def scalaFiles =
for {
file <- filesHere
if file.getName.endsWith(".scala")
} yield file
val forLineLengths =
for {
file <- filesHere
if file.getName.endsWith(".scala")
line <- fileLines(file)
trimmed = line.trim
if trimmed.matches(".*for.*")
} yield trimmed.length
}
Files.printFiles()
Files.printFilesIter()
Files.printScalaFiles()
Files.printScalaFiles2()
Files.printScalaFiles3()
Files.grepParens(".*asdf.*")
Files.grepGcd()
Files.grepGcd2()
println("Files.scalaFiles.toList [" + Files.scalaFiles.toList + "]")
println("Files.forLineLengths.toList [" + Files.forLineLengths.toList + "]")
(3)使用try表达式处理异常
object Exceptions {
def throws1 {
throw new IllegalArgumentException
}
//抛出异常,创建一个异常对象然后用throw关键字抛出
//throw的结果类型的表达式。如果n是偶数,返回n/2,否则异常抛出
def throws2(n: Int) = {
val half =
if (n % 2 == 0)
n / 2
else
throw new RuntimeException("n must be even")
half
}
def throws3 {
import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException
//try-catch捕获异常
try {
val f = new FileReader("input.txt")
// Use and close file
println("f [" + f + "]")
} catch {
case ex: FileNotFoundException => // 处理丢失的文件
println("ex [" + ex + "]")
case ex: IOException => // 处理其他I/o错误
println("ex [" + ex + "]")
}
}
//try-finally
def finally1 {
import java.io.FileReader
val file = new FileReader("input.txt")
try {
// Use the file
} finally {
file.close() // Be sure to close the file
}
}
import java.net.URL
import java.net.MalformedURLException
def urlFor(path: String) =
try {
new URL(path)
} catch {
case e: MalformedURLException =>
new URL("http://www.scala-lang.org")
}
def f(): Int = try { return 1 } finally { return 2 }
def g(): Int = try { 1 } finally { 2 }
}
try {
Exceptions.throws1
} catch {
case ex =>
println("ex [" + ex + "]")
}
try {
println("Exceptions.throws2(2) [" + Exceptions.throws2(2) + "]")
Exceptions.throws2(3)
} catch {
case ex =>
println("ex [" + ex + "]")
}
Exceptions.throws3
println("Exceptions.urlFor(\"blah\") [" + Exceptions.urlFor("blah") + "]")
println("Exceptions.f [" + Exceptions.f + "]")
println("Exceptions.g [" + Exceptions.g + "]")
(5)match匹配表达式
object Match {
def match1(args: Array[String]) {
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?")
}
}
def match2(args: Array[String]) {
val firstArg = if (!args.isEmpty) args(0) else ""
val friend =
firstArg match {
case "salt" => "pepper"
case "chips" => "salsa"
case "eggs" => "bacon"
case _ => "huh?"
}
println(friend)
}
}
Match.match1(Array())
Match.match1(Array("foo"))
Match.match1(Array("eggs"))
Match.match2(Array("chips"))
(6)变量范围
def printMultiTable() {
var i = 1
// only i in scope here
while (i <= 10) {
var j = 1
// both i and j in scope here
while (j <= 10) {
val prod = (i * j).toString
// i, j, and prod in scope here
var k = prod.length
// i, j, prod, and k in scope here
while (k < 4) {
print(" ")
k += 1
}
print(prod)
j += 1
}
// i and j still in scope; prod and k out of scope
println()
i += 1
}
// i still in scope; j, prod, and k out of scope
}
printMultiTable()
(7)重构指令式风格的代码
// 以序列形式返回一行乘法表
def makeRowSeq(row: Int) =
for (col <- 1 to 10) yield {
val prod = (row * col).toString
val padding = " " * (4 - prod.length)
padding + prod
}
// 以字符串形式返回一行乘法表
def makeRow(row: Int) = makeRowSeq(row).mkString
// 以字符串形式返回乘法表,每行占一行字符串
def multiTable() = {
val tableSeq = // 行记录字符串的序列
for (row <- 1 to 10)
yield makeRow(row)
tableSeq.mkString("\n")
}
println("multiTable [" + multiTable + "]")
网友评论