通用應用方法
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 的類別,也會產生建構函式代理。精確規則如下
-
為具體類別
C
建立建構函式代理伴生物件object C
,前提是該類別尚未有伴生物件,且在定義C
的範圍內也沒有定義或繼承其他名為C
的值或方法。 -
為具體類別產生建構函式代理
apply
方法,前提是- 該類別有伴生物件(可能已在步驟 1 中產生),且
- 該伴生物件尚未定義名為
apply
的成員。
每個產生的
apply
方法會轉發到類別的一個建構函式。它具有與建構函式相同的類型和值參數。
建構函式代理伴生物件本身無法用作值。必須使用 apply
選取代理伴生物件(或將其套用至參數,在此情況下會隱含插入 apply
)。
建構函式代理也不允許遮蔽一般定義。也就是說,如果
- 識別碼解析為建構函式代理,
- 同一個識別碼也在其他範圍中定義或匯入,
- 其他參考可以套用至(可能為空的)參數清單。也就是說,它會參考方法或包含套用方法作為成員的值。
動機
省略 new
會隱藏實作細節,讓程式碼更易於閱讀。即使需要新的規則,它可能會增加語言的感知規則性,因為案例類別已經提供函式呼叫建立語法(而且通常僅因這個原因而定義)。
本文中