在 GitHub 上編輯此頁面

通用應用方法

Scala 案例類別會產生 apply 方法,以便可以使用簡單的函式應用來建立案例類別的值,而不需要寫入 new

Scala 3 將此架構概括到所有具體類別。範例

class StringBuilder(s: String):
  def this() = this("")

StringBuilder("abc")  // old: new StringBuilder("abc")
StringBuilder()       // old: new StringBuilder()

這會運作,因為會與類別一起產生具有兩個 apply 方法的伴隨物件。物件看起來像這樣

object StringBuilder:
  inline def apply(s: String): StringBuilder = new StringBuilder(s)
  inline def apply(): StringBuilder = new StringBuilder()

合成物件 StringBuilder 及其 apply 方法稱為建構函式代理。即使是 Java 類別和來自 Scala 2 的類別,也會產生建構函式代理。精確規則如下

  1. 為具體類別 C 建立建構函式代理伴生物件 object C,前提是該類別尚未有伴生物件,且在定義 C 的範圍內也沒有定義或繼承其他名為 C 的值或方法。

  2. 為具體類別產生建構函式代理 apply 方法,前提是

    • 該類別有伴生物件(可能已在步驟 1 中產生),且
    • 該伴生物件尚未定義名為 apply 的成員。

    每個產生的 apply 方法會轉發到類別的一個建構函式。它具有與建構函式相同的類型和值參數。

建構函式代理伴生物件本身無法用作值。必須使用 apply 選取代理伴生物件(或將其套用至參數,在此情況下會隱含插入 apply)。

建構函式代理也不允許遮蔽一般定義。也就是說,如果

  • 識別碼解析為建構函式代理,
  • 同一個識別碼也在其他範圍中定義或匯入,
  • 其他參考可以套用至(可能為空的)參數清單。也就是說,它會參考方法或包含套用方法作為成員的值。

動機

省略 new 會隱藏實作細節,讓程式碼更易於閱讀。即使需要新的規則,它可能會增加語言的感知規則性,因為案例類別已經提供函式呼叫建立語法(而且通常僅因這個原因而定義)。

本文中