if
var age=25
val result = if(age>20) “worker” else “student”
println(result)
- 这段代码比java代码简短,并且result无需使用var变量,使用val为函数式编程风格
while循环
//求两个数的最大公约数
def gcdLoop(x:Long, y:Long) :Long = {
var a=x
var b=y
while( a != 0){
var temp = a
a = b % a
b = temp
}
b
}
var line=""
do {
line = readLine()
println(“Read: " + line)
} while (line !=”")
Scala 的 while 和 do-while 称为“循环”而不是表达式,是因为它不产生有用的返回值(或是返回值为 Unit ),可以写成 () 。() 的存在使得 Scala 的 Unit 和 Java 的 void 类型有所不同。
推荐尽量避免在代码中使用 while 循环,正如函数化编程要避免使用 var 变量一样。 而使用 while 循环时通常也会使用到 var 变量,因此在你打算使用 while 循环时需要特别小心,看是否可以避免使用它们。
for表达式
- 枚举集合元素
val filesHere = (new java.io.File(".")).listFiles
for(file <- filesHere)
println(file)
for(i <- 1 to 4) println(“Interation” +i)
- 过滤
for (file <- filesHere
if file.getName.endsWith(".scala")
if file.isFile
)
println(file)
- 嵌套迭代
for表达式支持多重迭代。
val filesHere = (new java.io.File(".")).listFiles
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.*")
注意上面代码中,两个迭代之间使用了 ; ,如果你使用 {} 替代 for 的 () 括号,你可以不使用 ;
val filesHere = (new java.io.File(".")).listFiles
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.*")
- 绑定中间变量
你可能注意到,前面代码使用了多次 line.trim 。如果 trim 是个耗时的操作,你可能希望 trim 只计算一次。Scala 允许你使用 = 号来绑定计算结果到一个新变量。绑定的作用和 val 类似,只是不需要使用 val 关键字。例如,修改前面的例子,只计算一次 trim,把结果保存在 trimmed 变量中。
val filesHere = (new java.io.File(".")).listFilesval filesHere = (new java.io.File(".")).listFiles
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)
trimmed=line.trim
if trimmed.matches(pattern)
} println(file + ":" + trimmed)
grep (".*gcd.*")
- 生成新集合
for 表达式也可以用来生产新的集合,这是 Scala 的 for表达式比 Java 的 for 语句功能强大的地方。它的基本语法如下:
for clauses yield body
关键字 yield 放在 body 的前面,for 每迭代一次,就产生一个 body 。yield 收集所有的 body 结果,返回一个 body 类型的集合。
用try表达式处理异常
-
抛出异常
val half =
if (n % 2 == 0)
n/2
else
throw new RuntimeException(“n must be even”) -
捕获异常
import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException
try {
val f = new FileReader("/home/hadoop/input.txt")
} catch {
case ex: FileNotFoundException => //handle missing file
case ex: IOException => //handle other I/O error
}
-
finally
Scala 也支持 finally 语句,你可以在 finally 块中添加一些代码。这些代码不管 try 块是否抛出异常,都会执行。比如,你可以在 finally 块中添加代码保证关闭已经打开的文件,而不管前面代码中是否出现异常 -
生成返回值
和大部分 Scala 控制结构一样,Scala 的 try-catch-finally 也生成某个值。比如下面的例子尝试分析一个 URL ,如果输入的 URL 无效,则使用缺省的 URL 链接地址:
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”)
}
通常情况下,finally 块用来做些清理工作,而不应该产生结果,但如果在 finally 块中使用 return 来返回某个值,这个值将覆盖 try-catch 产生的结果,不用return,就不会覆盖,比如:
def f(): Int = try { return 1 } finally { return 2}
- Match表达式
val args = Array("chips")
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?")
}
这段代码和 Java 的 switch 相比有几点不同:
一是任何类型的常量都可以用在 case 语句中,而不仅仅是 int 或是枚举类型。
二是每个 case 语句无需使用 break ,Scala不支持“fall through”。
三是Scala的缺省匹配为 _ ,其作用类似 java 中的 default。
而最关键的一点,是 scala 的 match 表达式有返回值。上面的代码使用的是 println 打印,而实际上你可以使用表达式,比如修改上面的代码如下:
val firstArg = if (args.length >0 ) args(0) else ""
val friend = firstArg match {
case "salt" => "pepper"
case "chips" => "salsa"
case "eggs" => "bacon"
case _ => "huh?"
}
println(friend)
不用break和continue咋办
从一组字符串中寻找以 .scala 结尾的字符串,但跳过以 - 开头的字符串。
java
int i=0;
boolean foundIt=false;
while(i <args.length) {
if (args[i].startWith("-")) {
i=i+1;
continue;
}
if(args[i].endsWith(".scala")){
foundIt=true;
break;
}
i=i+1;
}
scala
var i=0
var foundIt=false
while (i < args.length && !foundIt) {
if (!args(i).startsWith("-")) {
if(args(i).endsWith(".scala"))
foundIt=true
}
i=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)