鲁春利的工作笔记,好记性不如烂笔头
Scala只内置了为数不多的几种程序控制语句:if , while, for, try, match等。
1、判断(if)
格式:
if (A) B; else C
if (!A) C
package com.lucl.scala /** * @author luchunli */ object IfControlStructure { // 返回类型是可选的,默认最后一行的值为返回值,Scala可以根据返回值推导出返回类型 def getMax (a : Int, b : Int) = if (a > b) a else b; // 未指定else实际上为:else Unit,简写为() def getMin (a : Int, b : Int) = if (a > b) b; def main (args : Array[String]) { println(getMax(3, 5)); // 5 println(getMin(5, 3)); // 3 println(getMin(3, 5)); // () } }
2、循环(while/do)
package com.lucl.scala /** * @author luchunli */ object WhileControlStructure { def whileFunc () { var n = 10; // 如果n = 0, 不会有任何输出 while (n > 0) { print (n + ", "); n -= 1; } println; } def doWhileFunc () { var m = 10; // 如果m = 0,会输出一次0 do { print(m + ", "); m -= 1; } while (m > 0); } def main (args : Array[String]) { whileFunc(); doWhileFunc; var line = ""; while (line == "bye") { // line = readLine 被标记为@deprecated,采用如下方式实现 line = StdIn.readLine; // ...... } } }
说明:
对于while循环如果是(line = readLine()) != "bye"的话是无法退出while循环的,因为赋值语句的返回结果(即line = readLine()作为一个整体处理后的结果是Unit,然后再和bye进行比对)和字符串是不相等的。
比如:
var y = 2; varl x = y = 1; // 此时y=1, x=Unit(打印出来为())
3、枚举(for)
Scala中没有Java中的for(;;)形式的循环,其格式为:
for (i <- e) { E(i) }
for (i <- e1; j <- e2; if ...) { E(i) }
for (i <- e) yield E(i) // 生成集合
其中 <�C f的语法结构,在Scala中称为“生成器 (generator)”。
For表达式能用任意条件进行各种形式枚举,而在枚举的过程中能实现绝大部分的循环功能而不必使用变量。
遍历e中的元素,每次获取名为i的新值;对于每一次枚举,函数体E(i)都会被执行一次,而i在枚举时赋值。
e可以是各种集合,包括数组、列、表达式等,或是有上下界的数值范围。
package com.lucl.scala import java.io.File import scala.io.StdIn /** * @author luchunli */ object ForControlStructure { def main (args : Array[String]) { // 代码块 { for (i <- 1 to 5) print(i + ", "); // 1, 2, 3, 4, 5, println; // 指定步长 for (i <- 1 to (5, 2)) print(i + ", "); // 1, 3, 5, println; for (i <- 1 until 5) print(i + ", "); // 1, 2, 3, 4, println; for (i <- 1 to 3; j <- 1 to 3; if i < j) print (i + "-" + j + ", "); println; for (i <- "hello") print(i + ", "); // h, e, l, l, o, println; } // 代码块 { var array = Array("hello", "world", "!"); for (arr <- array) print(arr + " "); // hello world ! println; } // 代码块 { val files = (new File("D:\\LuclAppServ\\luchunli")).listFiles; for (file <- files; if file.isFile() && file.getName.endsWith(".gz")) println(file) } // 代码块 { // 生成新的集合 val res = for (i <- 1 to 5) yield 2 * i; println(res); // Vector(2, 4, 6, 8, 10) var str = for (i <- "hello".reverse) yield i; println(str); // olleh } } }
4、break和continue
Scala的内置的控制结构时,没有提到使用break和continue,Scala提供了多种方法来替代break和continue的作用。一个简单的方法是使用一个if语句来代替一个continue,使用一个布尔控制量来去除一个break。
下面的Java代码使用continue和break在循环结构中:
int i = 0; boolean fonudIt = false; while ( i < args.length) { if (args[i].startsWith("-")) { i += 1; continue; } if(args[i].endsWith(".scala")) { foundIt = true; break; } i += 1; }
使用if和boolean变量,逐句将这段实现使用Scala来实现(不使用break和continue)如下:
var i = 0; var foundIt = false; while (i < args.length && !foundId) { if (!args(i).startsWith("-") && args(i).endsWith(".scala")) { foundIt = true; } i += 1; }
可以看到,使用if (于前面continue条件相反)去掉了continue,而重用了foundIt布尔变量去掉了break。
5、匹配(match)
Scala的Match表达式支持从多个选择中选取其一,类似其它语言中的switch语句。
通常来说,Scala的match表达式支持任意的匹配模式。
a match { case e1 => E1 // 匹配元素e1 case e2 => E2 // 匹配元素e2 case _ => Eo // 其他情况 } # 给定类型 a match { case e1 : String : E1 case e2 : Int : E2 case _ : E3 }
和Java的switch相比有几点不同:
一、Java的case仅限于int或是枚举类型,Scala任何类型的常量都可以用在case语句中;
二、Java中每个case都必须有break,Scala每个case语句均无需使用break;
三、Java中缺省匹配为default,Scala的缺省匹配为”_”。
package com.lucl.scala /** * @author lucl */ object CaseControlStructure { def caseMethod1 (name : String) { name match { case "human" => println("human"); case "animal" => println("hahaha"); case _ => println("unknown"); } } def caseMethod2 (array : Array[Any]) { for (arg <- array) { arg match { case str : String => println("The string with value " + str + "."); case i : Int => println("The integer with value " + i + "."); case _ => println("Unknown type."); } } } def caseMethod3 (value : String) : String = { value match { case "a" => "All"; case "o" => "Oters"; case _ => "unknown"; } } def main(args: Array[String]): Unit = { // 接收固定参数并判断 caseMethod1("human"); // 接收数组并判断参数类型 var array = Array("hello", 1, 'c'); caseMethod2(array); // 带有返回值 var checkType = caseMethod3("a"); println(checkType); } }
6、异常处理(throw/try)
Scala的异常处理和其它语言比如Java类似。
def half (n:Int) : Int = { if (n % 2 == 0) { n / 2; } else { throw new RuntimeException("n must be even"); } }
try-catch表达式的基本用法和Java一样,如果try块中代码在执行过程中出现异常,将逐个检测每个catch块。
import java.io.FileReader import java.io.FileNotFoundException import java.io.IOException try { val f = new FileReader("input.txt"); } catch { case ex : FileNotFoundException ==> // handle missing file case ex : IOException => // handle other I/O error }
Scala也支持finally语句,不管try块是否抛出异常,都会执行。
try {函数体} catch {case ...; case ...} finally {A.close();} // 通过异常赋值 def f():Int = try{1} finally {2} // 或 def urlFor(path:String) = try { new URL(path) } catch { case e: MalformedURLException => new URL("http://www.scala-lang.org") }