Scala 3 — 書籍

不變值

語言

在純函數式程式設計中,僅使用不變值。在 Scala 中,這表示

  • 所有變數都建立為 val 欄位
  • 僅使用不變集合類別,例如 ListVector,以及不變的 MapSet 類別

僅使用不可變變數會引發一個有趣的問題:如果一切都不可變,那麼任何事情如何改變?

當使用集合時,一個答案是您不會變異現有集合;相反,您將函式套用至現有集合以建立新的集合。這就是像 mapfilter 之類的高階函式發揮作用的地方。

例如,想像您有一個名稱清單(List[String]),全部是小寫,您想要找出所有以字母 "j" 開頭的名稱,然後您想要將這些名稱大寫。在 FP 中,您撰寫此程式碼

val a = List("jane", "jon", "mary", "joe")
val b = a.filter(_.startsWith("j"))
         .map(_.capitalize)

如所示,您不會變異原始清單 a。相反,您將篩選和轉換函式套用至 a 以建立新的集合,並將該結果指定給新的不可變變數 b

類似地,在 FP 中,您不會使用可變 var 建構函式參數建立類別。也就是說,您不會撰寫此內容

// don’t do this in FP
class Person(var firstName: String, var lastName: String)
             ---                    ---

相反,您通常會建立 case 類別,其建構函式參數預設為 val

case class Person(firstName: String, lastName: String)

現在,您將 Person 實例建立為 val 欄位

val reginald = Person("Reginald", "Dwight")

然後,當您需要對資料進行變更時,您可以使用 case 類別附帶的 copy 方法來「在您建立副本時更新資料」,如下所示

val elton = reginald.copy(
  firstName = "Elton",   // update the first name
  lastName = "John"      // update the last name
)

還有其他處理不可變集合和變數的技術,但希望這些範例能讓您了解這些技術。

根據您的需求,您可以建立列舉、特質或類別,而不是 case 類別。請參閱 資料建模 章節以取得更多詳細資訊。

此頁面貢獻者