Часто бывает удобно иметь определения, доступные для всего пакета,
когда не нужно придумывать имя для оболочки object
, которая их содержит.
Scala 2 предоставляет объекты пакета (package objects) в виде удобного контейнера, общего для всего пакета.
Объекты пакета могут содержать произвольные виды выражений, а не только переменные и методы. Например, они часто используются для хранения псевдонимов типа и наборов неявных преобразований доступных всему пакету. Объекты пакета могут также наследоваться от классов и трейтов Scala.
В будущей версии Scala 3 объекты пакета будут удалены в пользу определений верхнего уровня.
По соглашению, исходный код объекта пакета обычно помещается в файл под названием package.scala
.
Каждому пакету разрешено иметь один объект пакета. Любые выражения, содержащиеся в объекте пакета, считаются членами самого пакета.
В Scala 3 любое определение может быть объявлено на верхнем уровне пакета. Например, классы, перечисления, методы и переменные.
Любые определения, размещенные на верхнем уровне пакета, считаются членами самого пакета.
В Scala 2 верхнеуровневый метод, определения типов и переменных должны были быть заключены в объект пакета. Их все еще можно использовать в Scala 3 для обратной совместимости. Вы можете увидеть, как они работают, переключая вкладки.
См. пример ниже. Предположим, есть старший класс Fruit
и три наследуемых от него объекта Fruit
в пакете.
gardening.fruits
:
// в файле 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
.
Вот как это делается:
// в файле 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}")
}
}
// в файле 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}")
Для примера, следующий объект PrintPlanted
импортирует planted
и showFruit
точно так же, как с вариантом импорта класса Fruit
,
используя групповой стиль импорта пакета gardening.fruits
:
// в файле PrintPlanted.scala
import gardening.fruits._
object PrintPlanted {
def main(args: Array[String]): Unit = {
for (fruit <- planted) {
showFruit(fruit)
}
}
}
// в файле PrintPlanted.scala
import gardening.fruits.*
@main def printPlanted(): Unit =
for fruit <- planted do
showFruit(fruit)
Объединение нескольких определений на уровне пакета
Часто в вашем проекте может быть несколько повторно используемых определений, заданных в различных модулях, которые вы хотите агрегировать на верхнем уровне пакета.
Например, некоторые вспомогательные методы в трейте FruitHelpers
и некоторые псевдонимы терминов/типов в свойстве FruitAliases
.
Вот как вы можете разместить все их определения на уровне пакета fruit
:
Объекты пакета ведут себя также, как и любые другие объекты. Это означает, что вы можете использовать наследование, при этом сразу нескольких трейтов:
package gardening
// `fruits` наследует свои элементы от родителей.
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.*
Contributors to this page:
Contents
- Введение
- Основы
- Единобразие типов
- Классы
- Значения Параметров По умолчанию
- Именованные Аргументы
- Трейты
- Кортежи
- Композиция классов с трейтами
- Функции Высшего Порядка
- Вложенные Методы
- Множественные списки параметров (Каррирование)
- Классы Образцы
- Сопоставление с примером
- Объекты Одиночки
- Регулярные Выражения
- Объект Экстрактор
- Сложные for-выражения
- Обобщенные Классы
- Вариантность
- Верхнее Ограничение Типа
- Нижнее Ограничение Типа
- Внутренние классы
- Члены Абстрактного Типа
- Составные Типы
- Самоописываемые типы
- Контекстные параметры, также известные, как неявные параметры
- Неявные Преобразования
- Полиморфные методы
- Выведение Типа
- Операторы
- Вызов по имени
- Аннотации
- Пакеты и Импорт
- Объекты Пакета