通常,讓定義在整個套件中都可以存取很方便,而且不需要發明一個包裝器 object
的名稱來包含它們。
Scala 2 提供 套件物件 作為一個方便的容器,可以在整個套件中共用。
套件物件可以包含任意定義,不只是變數和方法定義。例如,它們經常被用來儲存套件範圍的類型別名和隱式轉換。套件物件甚至可以繼承 Scala 類別和特質。
在未來的 Scala 3 版本中,套件物件將被移除,改用頂層定義。
根據慣例,套件物件的原始碼通常會放在名為 package.scala
的原始碼檔案中。
每個套件允許有一個套件物件。放在套件物件中的任何定義都被視為套件本身的成員。
在 Scala 3 中,任何類型的定義都可以在套件的頂層宣告。例如,類別、列舉、方法和變數。
置於套件頂層的任何定義都被視為套件本身的成員。
在 Scala 2 中,頂層方法、類型和變數定義必須包覆在套件物件中。這些在 Scala 3 中仍然可用,以維持向後相容性。您可以透過切換標籤查看它們如何運作。
請參閱以下範例。假設首先在套件 gardening.fruits
中有一個類別 Fruit
和三個 Fruit
物件
// in file gardening/fruits/Fruit.scala
package gardening.fruits
case class Fruit(name: String, color: String)
object Apple extends Fruit("Apple", "green")
object Plum extends Fruit("Plum", "blue")
object Banana extends Fruit("Banana", "yellow")
現在假設您想將變數 planted
和方法 showFruit
直接置於套件 gardening.fruits
中。以下說明如何執行此操作
// in file gardening/fruits/package.scala
package gardening
package object fruits {
val planted = List(Apple, Plum, Banana)
def showFruit(fruit: Fruit): Unit = {
println(s"${fruit.name}s are ${fruit.color}")
}
}
// in file gardening/fruits/package.scala
package gardening.fruits
val planted = List(Apple, Plum, Banana)
def showFruit(fruit: Fruit): Unit =
println(s"${fruit.name}s are ${fruit.color}")
作為如何使用此變數的範例,下列程式會以與匯入類別 Fruit
完全相同的方式匯入 planted
和 showFruit
,使用套件 gardening.fruits
的萬用字元匯入
// in file PrintPlanted.scala
import gardening.fruits._
object PrintPlanted {
def main(args: Array[String]): Unit = {
for (fruit <- planted) {
showFruit(fruit)
}
}
}
// in file printPlanted.scala
import gardening.fruits.*
@main def printPlanted(): Unit =
for fruit <- planted do
showFruit(fruit)
在套件層級匯聚多個定義
您的專案通常可能有多個可重複使用的定義在各種模組中定義,您希望在套件的頂層匯聚這些定義。
例如,特質 FruitHelpers
中的一些輔助方法,以及特質 FruitAliases
中的一些術語/類型別名。以下是您如何將它們的所有定義置於 fruit
套件層級的方式
套件物件就像其他物件,這表示您可以使用繼承來建置它們。因此,我們在此將輔助特質混合為套件物件的父類別。
package gardening
// `fruits` instead inherits its members from its parents.
package object fruits extends FruitAliases with FruitHelpers
在 Scala 3 中,建議使用 export
將多個物件的成員組合到單一範圍中。在此,我們定義私有物件,將其混合到輔助特質中,然後在頂層匯出其成員
package gardening.fruits
private object FruitAliases extends FruitAliases
private object FruitHelpers extends FruitHelpers
export FruitHelpers.*, FruitAliases.*