2 表達式 選擇 循環 函數

Scala中,幾乎全部的語法結構都是有值的(包括表達式和語句塊...)java

1 IF/ELSE結構函數

val s = if(x > 0) 1 else -1spa

等價於 if(x > 0) s = 1 else s = -1scala

 

注:既然表達式是有值的,那麼必然也是有類型的。如上述表達式的類型是:Int指針

若是出現if分支和else分支類型不一樣,好比:if(x > 0) 」positive」 else -1,那麼整個表達式的類型是:String和Int的公共基類Anyorm

 

若是一個表達式沒有任何有效值,能夠用Unit表示其類型,用()表示,至關於C++中的void:對象

如:if(x > 0) 1 else ()遞歸

 

默認狀況下,Scala解釋器只能解釋一行代碼,若是你想使用多行代碼,如:編譯器

if(x > 0) 1it

else if(x == 0) 0 else -1

則必須在else前加上{},如:

if(x > 0) {1

} else if(x == 0) 0 else -1

 

2 語句的結束

Scala中的語句結束時不須要加分號,除非一行內寫了多條語句,如:

if (n > 0) {r = r * n; n -= 1}

 

若是想將一行比較長的語句寫在多行中,斷行時只要第一行最後一個字符不能做爲語句結束符便可,例如:+ - …

s = s0 + s1 + s2 –

s3 –s4

 

若是是語句塊的話,最好使用{,如:

if (n > 0){

    r = r * n

n -= 1

}

 

3 Scala的語句塊

在Scala中,語句塊{..}的結果是一個表達式,該語句塊的值就是塊中最後一個表達式的值

在Scala中,賦值語句的返回類型爲Unit,所以不能出現鏈式賦值,如:x = y = 1,這是錯誤的

 

4 輸入輸出

輸出:

print(「benxintuzi」)                           不帶換行符

println(「benxintuzi」)                         帶換行符

printf(「Hello, %s\n」, 「benxintuzi」)           格式化輸出

輸入:

var name = readLine(「Your name :」),用於從控制檯讀取一行輸入,其中的參數」Your name :」爲提示符,此外,還能夠以下讀取不一樣類型的內容:

val v1 = readInt()/readDouble()/readByte()/readShort()/readChar()

 

5 循環

While/do循環結構與C++、Java無異

Scala中的for循環結構以下:

for(i <- 表達式)

例如,for(i <- 0 util s.length){ // [0, s.length - 1]

       Sum += s(i)

      }

說明:Scala中並無提供break或者continue來退出循環,若是想實現退出循環,則可使用以下方式:

1 使用Boolean型的控制變量

2 使用嵌套函數,從函數中return

3 使用Breaks對象中的break方法,如:

import scala.util.control.Breaks._

breakable{

    for(…){

       if(…) break;  // 退出breakable塊

}

}

 

for循環的高級特性:

特性1:for(i <- 1 to 3; j <- 1 to 3) print(…) // 多個表達式

特性2:for(i <- 1 to 3; j <- 1 to 3 if i != j) print(…) // 注:只能加一個判斷,而且前邊不能有分號

特性3:for(i <- 1 to 3; from = 4 – i; j <- from to 3) print(…) // 可使用任意多個定義

特性4:for(i <- 1 to 10) yield i % 3 // 以yield開始的循環體會構造出一個結果集合:Vector{1, 2, 0, 1, 2, 0, 1, 2, 0, 1}

 

6 Scala函數

1 非遞歸函數定義時能夠不給出函數返回類型:

def abs(x : Int) = if(x >= 0) x else –x

2 遞歸函數必須給出返回類型:

def fact(n : Int) : Int = if(n <= 0) 1 else n * fact(n - 1)

若是沒有類型,Scala解釋器沒法肯定n * fact(n - 1)的類型是Int(回憶一下: C/C++中的結構體中,不能有包含自身的變量,可是能夠有指向自身的指針,就是由於編譯器沒法肯定結構體的大小)

3 默認參數和指定參數

def decorate(str : String, left : String = 「[」, right : String = 「]」) = left + str + right // left和right都帶有默認值 

調用decorate(「benxintuzi」)-----[benxintuzi]

調用decorate(「benxintuzi」, 「<」, 「>」)-----<benxintuzi>

 

注:在調用時,能夠顯示指定某個參數的值,其順序不必和定義時一致,如:

decorate(left = 「((」, str = 「tuzi」, right = 「))」)-----((tuzi)) [可是不建議這樣作,最好保持定義時的順序]

4 變長參數

def sum(agrs : Int*) = {

    var result = 0

    for(arg <- args) result += arg

    result

}

可使用任意多個參數調用sum,如:val s = sum(1, 2, 3)

 

注意:若是傳入的是單個區間,如val s = sum(1 to 5),則必須告訴編譯器將這個參數看成序列Seq來處理,具體以下:

val s = sum(1 to 5 : _*),該語法在遞歸函數中經常使用

 

7 過程

若是一個函數不須要返回有效值,可使用過程來表示,具體以下:

def box(s : String){

    Var border = 「-」 * s.length + 「--\n」

    Println(border + 「|」 + s + 「|\n」 + border)

}

 

等價於:

def box(s : String) : Unit = {

    Var border = 「-」 * s.length + 「--\n」

    Println(border + 「|」 + s + 「|\n」 + border)

}

 

8 Lazy Value

當val被聲明爲lazy時,其初始化將被推遲到首次對其調用時:

Lazy val words = scala.io.Source.fromFile(「/usr/share/dict/words」).mkSring

只有調用words時,纔會打開這個文件。該機制對於開銷比較大的初始化語句十分有效。

 

9 異常

Scala中的異常機制與C++和Java相似。好比,throw new IllegalArgumentException(「x should not be negative」)

和Java同樣,拋出的異常對象必須是java.lang.Throwable的子類。

throw表達式的類型是Nothing

捕獲異常採用的是模式匹配語法:

try{

    Process(new URL(「…」))

} catch{

    case _ : MalformedURLException => println(「Bad URL」)

    case ex : IOException => ex.printStackTrace()

}

注:在不須要使用捕獲到的異常時,用 _ 代替變量名

 

                                                                 -----源自《快學Scala》 Chapter 2

相關文章
相關標籤/搜索