當您查看 Scala 集合類別中 map
方法的 Scaladoc 時,您會看到它被定義為接受一個函式
def map[B](f: (A) => B): List[B]
-----------
的確,Scaladoc 明確指出,「f
是要套用至每個元素的函式。」但儘管如此,您還是可以將一個方法傳遞到 map
中,而且它仍然可以運作
def times10(i: Int) = i * 10 // a method
List(1, 2, 3).map(times10) // List(10,20,30)
您是否曾想過這是如何運作的—您如何將一個方法傳遞到 map
中,而它預期的是一個函式?
這背後的技術稱為Eta 擴充。它將方法類型的表達式轉換為等效的函式類型表達式,而且它會無縫且安靜地執行此操作。
方法和函式之間的差異
從歷史上來看,方法一直是類別定義的一部分,儘管在 Scala 3 中,您現在可以在類別之外使用的方法,例如 頂層定義 和 擴充方法。
與方法不同,函式本身就是完整的物件,使其成為一級實體。
它們的語法也不同。此範例顯示如何定義方法和執行相同任務的函式,判斷給定的整數是否為偶數
def isEvenMethod(i: Int) = i % 2 == 0 // a method
val isEvenFunction = (i: Int) => i % 2 == 0 // a function
函式確實是一個物件,因此您可以像使用任何其他變數一樣使用它,例如將其放入清單中
val functions = List(isEvenFunction)
// this example shows the Scala 2 error message
val methods = List(isEvenMethod)
^
error: missing argument list for method isEvenMethod
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `isEvenMethod _` or `isEvenMethod(_)` instead of `isEvenMethod`.
相反地,技術上來說方法不是一個物件,因此在 Scala 2 中您不能將方法放入 清單
中,至少不能直接放入,如範例所示
val functions = List(isEvenFunction) // works
val methods = List(isEvenMethod) // works
Scala 3 的重點在於 Eta Expansion 技術的改進,因此現在當您嘗試將方法用作變數時,它就能運作了,您不必自己處理手動轉換。
對於這本入門書籍,您需要知道的重要事項是
- Eta Expansion 是讓您可以像使用函式一樣使用方法的 Scala 技術
- Scala 3 中的技術已獲得改進,幾乎完全無縫
有關此運作方式的更多詳細資訊,請參閱參考文件中的 Eta Expansion 頁面。
此頁面的貢獻者
內容
- 簡介
- Scala 功能
- 為什麼選擇 Scala 3?
- Scala 入門
- Hello, World!
- REPL
- 變數和資料類型
- 控制結構
- 網域建模
- 方法
- 一級函式
- 單例物件
- 集合
- 脈絡抽象
- 頂層定義
- 摘要
- 類型初探
- 字串內插
- 控制結構
- 網域建模
- 工具
- OOP 建模
- FP 建模
- 方法
- 方法功能
- Scala 3 中的主要方法
- 摘要
- 函式
- 匿名函式
- 函式變數
- Eta 擴充
- 高階函式
- 撰寫您自己的 map 方法
- 建立傳回函式的函式
- 摘要
- 封裝和匯入
- Scala 集合
- 集合類型
- 集合方法
- 摘要
- 函數式程式設計
- 什麼是函數式程式設計?
- 不可變值
- 純函數
- 函數是值
- 函數式錯誤處理
- 摘要
- 類型和類型系統
- 推斷類型
- 泛型
- 交集類型
- 聯集類型
- 代數資料類型
- 變異
- 不透明類型
- 結構類型
- 相依函數類型
- 其他類型
- 脈絡抽象
- 擴充方法
- 內容參數
- 內容界限
- 已給定匯入
- 類型類別
- 多重宇宙等式
- 隱式轉換
- 摘要
- 並行處理
- Scala 工具
- 使用 sbt 建置和測試 Scala 專案
- 工作表
- 與 Java 互動
- 適用於 Java 開發人員的 Scala
- 適用於 JavaScript 開發人員的 Scala
- 適用於 Python 開發人員的 Scala
- 下一步