if 運算式


要在某條件成立時才進行某些動作,Scala提供了if運算式,一個例子如下:
var filename = "default.properties"
if(!args.isEmpty) {
    filename = args(0)
}

這 個範例中,預設的檔案名稱是default.properties,如果使用者有提供命令列引數,則args不為空,isEmpty會傳回false,所 以!args.isEmpty的結果是true,所以if條件成立,將filename設定為使用者所提供的命令列引數。

在Scala中,如果if中只有一個陳述句,則大括號可以不用撰寫,所以上例也可以這麼寫:
var filename = "default.properties"
if(!args.isEmpty)
    filename = args(0)

if可以搭配else,在if條件不成立時,執行else中定義的程式碼,所以上例也可以這麼寫:
var filename = ""
if(args.isEmpty)
    filename = "default.properties"
else
    filename = args(0)

在Scala 中一個重要的特性就是,if..else是個運算式(expression),也就是說if..else會有傳回值,傳回值就是if或else中最後一個 語句。由於Scala鼓勵你使用val宣告變數,你可以利用if...else運算式會傳回值的特性,將上例改寫為以下:
val filename = if(args.isEmpty) "default.properties" else args(0)

如果沒有提供命令列引數,則args.isEmpty為true,if條件成立,所以傳回"default.properties"的字串給filename,否則傳回args(0)的值給filename。

if..else為運算式的特性,可以讓Scala撰寫簡潔的程式碼,例如以下是個簡單的判斷輸入數是奇數或偶數的程式:
print("輸入整數:")
val input = readInt
printf("%d 為 %s", input, if(input % 2 == 0) "偶數" else "奇數")

if..else運算式的傳回值,是區塊中的最後一個語句,如果if..else中丟出了例外會如何呢?
val filename = if(!args.isEmpty) 
args(0)
else
throw new RuntimeException("必須提供引數")
println(filename)

這個例子是可通過編譯並運行的,執行時其實是先運算if..else,如果有提供命令列引數,則filename變數會被宣告並設定為args(0),否則else中會丟出例外,所以就不會宣告filename變數了。

if.. else既然是運算式,就上例來說,條件成立是會傳回值,那丟出例外時是否有傳回值?丟出例外時,基本上是標示其傳回Nothing,Nothing是Scala型態架構中最底層的 型態,
如此就可通過編譯器對if..else運算式的語法檢查不過實際上並沒有Nothing的實例,傳回Nothing代表著程式異常終止例外丟出就是跳離該行執行,所以filename變數的宣告就沒有執行。