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