1. 程式人生 > >scala 入門(5) -- 內建控制結構

scala 入門(5) -- 內建控制結構

根本你以為婚姻就是長期的賣淫 —— 傾城之戀

參考

《Scala 程式設計》

重要理解

Scala 中,幾乎所有的控制語句都會產生某個值

if 語句

先來看一個指令式形式的 scala 程式碼:

var filename = "default.txt"
if(!args.isEmpty)
    filename = args(0)

程式碼的作用是當輸入的引數不為空時,將引數值給 filename,否則為 default.txt

但是,上面有說到的,其實 if 語句也是會產生值返回的,下面的是函式式風格的 scala

val filename = 
    if
(!args.isEmpty) args(0) else "default.txt"

實現的效果是一樣的,區別在於:
- 使用了 val,節省了審查變數作用域的時間

for 表示式

常用 for 迴圈

scala> for (i <- 1 to 4)
     |    print(i+" ")
1 2 3 4
scala> for (i <- 1 until 4)
     |    print(i+" ")
1 2 3

另外,scala 中很少使用 for (i <- 0 to array.length-1) 這種形式來遍歷陣列,因為其集合本身可以直接被列舉 for(i <- array)

過濾

scala> for (i <- 1 to 10 if i%2==0)
     |    print(i+" ")
2 4 6 8 10

直接在遍歷語句後加入判斷條件

製造新集合

scala> val oddnums = for (i <- 1 to 10 if i%2!=0) yield {i}
oddnums: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 3, 5, 7, 9)

異常處理

丟擲異常

scala 丟擲異常的表達跟 Java 一樣

throw
new IllegalArgumentException

其實,throw 也是有返回值的,其丟擲異常的型別為 Nothing,但其實是用不上的

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("input.txt")
    // 使用並關閉檔案
}catch{
    case ex: FileNotFoundException => // 處理丟失的檔案
    case ex: IOException => // 處理其他的 I/O 錯誤
}

finally 子句

finally 子句的作用在於,不管程式碼以何種方式結束(正常或出錯),都會自行其中的程式碼

import java.io.FIleReader

val f = new FIleReader("input.txt")

try {
    // 使用檔案
} finally {
    file.close(); // 確保檔案的關閉
}

產生值

跟其他控制語句一樣,try-catch 也會有返回值

import java.net.URL
improt java.net.MalformedURLException

def urlFor(path:String) = 
    try {
        new URL(path)
    } catch {
        case e: MalformedURLException =>
            new URL("http://www.scala-lang.org")
    }

上面的程式碼中,返回的結果是,如果沒有異常丟擲,則對應 try 子句的結果,如果有異常丟擲且被捕獲,則對應相應的 catch 子句,如果有異常但是沒有捕獲的話,就沒有返回結果了

匹配(match)表示式

match 表示式類似於其他語言中的 switch 語句

val firstArg = if (args.length>0) args(0) else ""

firstArg = match (

    case "salt" => println("pepper")
    case "chips" => println("salsa")
    case _ => println("huh?")

)

在這裡,需要注意的是,在 scala 中,break 是隱含在 match 中的,也就是說,scala 預設不允許從上一個備選項中跳到下一個備選項

另外,case 比較的樣本不在侷限於 整數型別 和 列舉常量 了

同樣,match 也能產生返回值

val firstArg = if (args.length>0) args(0) else ""

val friend = 
    firstArg = match (

        case "salt" => "pepper"
        case "chips" => "salsa"
        case _ => "huh?"

    )

println(friend)

後記

這一章沒有記錄書上的挺多,一方面其在後面章節中會詳細介紹,另一方面跟 Java 基本類似,也就打算先放著先,以便節省時間