Scala基礎應用(1)- 基本語法
本章主要講解Scala基本語法,如何定義變量,函數,基本控制結構等。
1. 解釋器
Scala可以像其它腳本語言一樣,邊解釋邊運行,但實際項目中一定是通過編譯後再運行
- 安裝好Scala後,在控制檯運行scala即進入解釋器環境
- 另外可以在scala後面加上scala腳本文件,也可直接執行腳本
- 解釋器可以多行輸入,按兩次回車退回編寫
- 輸入:quit 或者 :q 退出解釋器
2. 變量定義
- 變量有兩種:var 和 val, 其中var定義的變量可以重新賦值,val定義的變量是隻讀的,不可重新賦值。
- var和val定義的變量可以進行類型推斷,如C#中的var
變量定義樣式:
var或者val 變量名: 類型 = 初始值 如: var variableName1: String = "hello world!" val variableName2: String = "hello world!"
3. 函數定義
函數定義的樣式如下:
def 函數名(變量1:類型, 變量2: 類型): 返回類型 = { 函數體 }
如果函數體可以用一行寫完,可以省略大括號
如: def max(x: Int, y: Int) = if (x >y) x else y
函數字面量 (literal)
函數字面量可以理解爲Java/C#的匿名函數,樣式如下: (變量1: 類型, 變量2: 類型) => { 函數體 } 同理這裏的大括號裏的函數體如果一行可以寫完,也可以省略大括號 函數字面量的實際工作原理是:編譯器會將函數字面量展開爲一個繼承自scala.FunctionN的內部類 例: val test = (x: String) => x 其它字面量與Java一樣,有Java經驗的可以略過,但要了解Symbol字段量 如: def test(r: Symbol) { println(r) } test('mytest)
4. 基本控制
4.1 if
樣式
if (條件) { 執行體 } else { 執行體 }
注意:scala裏的表達式都有返回值,如:
val hello = if (args.isEmpty) "empty" else args(0)
4.2 While
樣式
while(條件) { 執行體 } 如: var i = 0 while (i < 10) { println(i) }
注意: 這樣寫while循環是指令式(imperative)編程,如C#, Java…, scala允許使用指令式編程,但scala更傾向於一種更爲函數式的編程風格。
4.3 do-while
樣式
do { 執行體 } while (條件) do-while 與while很類似,只是把條件寫在最後
4.4 for
4.4.1 遍歷集合
樣式
for (變量 <- 集合) { 執行體 } 同理,如果執行體一行可以寫完,大括號也可以省略 例: for (c <- "this is a test string") println(c) 記住,變量c是val, 執行體裏不可以重新賦值
4.4.2 過濾
樣式
for (變量 <- 集合 if 條件1; if 條件2) { 執行體 } 如: for (c <- "this is a test string" if c == 't') println(c)
4.4.3 嵌套枚舉
樣式
for (變量1 <- 集合1 if 條件1; if 條件2; 變量2 <- 集合2 if 條件3; if 條件4) { 執行體 } 如: for { c <- "this is a test string" if c == 't' || c == 's' s <- c.toString if s == 't' } println (s)
注意,if 條件後面的分號, 這裏for後面的小括號可以使用大括號,好處是不用寫分號
4.4.4 流間(mid-stream)變量綁定
直接上代碼:
for {
c <- "this is a test string"
if c == 't' || c == 's'
str = c.toString // 流間變量也是val
s <- str
if s == 't'
} println (s)
4.4.5 製造新集合
樣式
for {子句} yield { 執行體 } 如: val result = for { c <- "this is a test string" if c == 't' || c == 's' str = c.toString // 流間變量也是val s <- str if s == 't' } yield s for(c <- result) println (c)
4.5 foreach
在scala裏,很多類都有foreach函數,使用方法如下:
變量.foreach(函數)
如:
"this is a test.".foreach(println)
5. 異常處理
- 拋出異常與Java一樣, 如: throw new IllegalArgumentException
捕獲異常
樣式: try { 執行體 } catch { case ex: 異常類型1 => 執行體 case ex: 異常類型2 => 執行體 } finally { 執行體 } 與java的區別: 不需要throws 另外, try-catch-finally 與其它控制結構一樣有返回值, 並且與 java有區別是finally低於try執行體的返回值,所以儘量不在finally裏返回值
6. match
match 類似於Java/C#中的switch, 但match的case範圍更廣泛,幾乎可以case所有值
樣式
變量 match { case 值1 => 執行體 case 值2 => 執行體 case _ => 執行體 }
7. 包
樣式
package 包名1 { 定義體 package 包名2 { 定義體 } } 包的聲明有點類似於C#的namespace的聲明方式,允許嵌
8.引用
樣式
import 包名.類 / import 包名.變量 // 引用某個類或變量 import 包名._ / import 包名.{_} // 引用包或類下面所有的定義, 這兩個聲明同義 import 包名.{類或變量} // 只引用類,或類成員 import 包.{<原始名> => <新名>} // 引用包/類/變量,並重命名 import 包.{<原始名> => _, _} // 引用包下所有成員,但<原始名>對應的成員除外
幾個內建引用
import java.lang._ // java.lang包的所有成員 import scala._ // scala包的所有成員 import Preder._ // Predef對旬的所有成員
9. 訪問修飾符
- private: 私有
- protected: 只能在子類中訪問,同一個包的其它類不可以訪問。 (與java不同)
- public: 缺省下,所有沒有加訪問修飾符的成員都是public的,而且不用顯示聲明