本文進入 Scala 函數式核心領域,介紹四大基礎集合類型:Option、Tuple、Set/Map、List,以及增強版 Array。這些類型提供全新程式設計抽象,配合物件特性可寫出極簡潔代碼。
Java 用 null 表示「無值」,易致 NullPointerException。Scala Option[T] 為泛型密封類,兩個子類:
Some[T](value):包裝實際值None:表示無值(單例)Map.get 回傳 Option[V],精確區分「鍵不存在」與「值為 null」:
val teams = Map("New England" -> "Patriots", "Miami" -> "Dolphins", "Los Angeles" -> null)
teams.get("Miami") // Some("Dolphins")
teams.get("Los Angeles") // Some(null) 鍵存在但值為 null
teams.get("Sacramento") // None 鍵不存在
def show(opt: Option[String]) = opt match {
case Some(x) => x
case None => "No team found"
}
show(teams.get("Miami")) // "Dolphins"
模式比對同時完成類型檢查、值提取與分支,免去 get() 呼叫與 null 檢查。
Tuple 為固定大小、異構、不可變容器,建構語法極簡:
val tuple = ("Ted", "Scala", Date.parse("3/7/2006"))
tuple._1 // "Ted"
tuple._2 // "Scala"
tuple._3 // Date 物件
適用場景:多返回值、臨時資料組合、避免建立專用 DTO 類別。Map 實質為二元 Tuple 集合。
Scala Array[T] 為泛型類別,繼承豐富特質層級(Mutable、RandomAccessSeq、Iterable...),支援函數式操作:
args.foreach(arg => println(arg)) // 遍歷
val scalaProgs = programmers.filter(p => p.skills.contains("Scala")) // 過濾
scalaProgs.foreach(p => p.salary += 5000) // 副作用操作
val raised = scalaProgs.map(p => new Person(..., p.salary + 5000, ...)) // 轉換產生新陣列
索引存取用圓括號 args(i),長度屬性 .length。
List[T] 為不可變、線性、支援高效頭尾操作的單向鏈表:
val list = List("Ted", "Amanda", "Luke")
list.head // "Ted"
list.tail // List("Amanda", "Luke")
list.last // "Luke"
list.isEmpty // false
def count(list: List[String]): Int = list match {
case h :: t => count(t) + 1 // h 為頭,t 為尾
case Nil => 0
}
:: 為右結合建構子,Nil 為空列表。模式比對 h :: t 同時解構頭尾並綁定變數。尾遞歸編譯器優化為迴圈,無堆疊溢位風險。
val list = "Ted" :: "Amanda" :: "Luke" :: "Don" :: "Martin" :: Nil
注意::: 以冒號結尾故為右結合,最右端必須為 List(Nil)。
def greet(list: List[String]): Int = list match {
case "Amanda" :: t => println("Hey, Amanda!"); count(t) + 1
case h :: t => count(t) + 1
case Nil => 0
}
首案例直接匹配特定值 "Amanda",餘下綁定 t。通配符 _ 可忽略不需的變數:case _ :: t => ...。
val arr = Array("Ted", "Amanda", "Luke")
arr.foreach(s => s match {
case "Amanda" => println("Hey, Amanda!")
case _ => // 忽略
})
Scala 集合庫融合函數式遺產與物件實用性:Option 消除 null、Tuple 輕量聚合、Array 增強互通、List 遞歸核心。警惕濫用 Tuple 取代領域模型——頻繁出現的結構應定義具名類別。享受雙範式帶來的表達力!