Объекты пакета

Что такое объекты пакета, не так понятие, но их использование?

Я попытался получить работу в качестве примера и единственную форму, которую я взялся за работу, был следующие:

package object investigations {
    val PackageObjectVal = "A package object val"
}

package investigations {

    object PackageObjectTest {
        def main(args: Array[String]) {
            println("Referencing a package object val: " + PackageObjectVal)
        }
    }
}

Наблюдения, которые я сделал до сих пор:

package object _root_ { ... }

запрещен (который разумен),

package object x.y { ... }

также запрещен.

Кажется, что объект пакета должен быть объявлен в пакете непосредственного родителя и, если записано как выше, разграниченная форма объявления пакета фигурной скобки требуется.

Действительно ли они широко используются? Если так, как?

89
задан Peter Mortensen 16 May 2013 в 17:01
поделиться

3 ответа

Обычно объект пакета помещается в отдельный файл с именем package.scala в пакете, которому он соответствует. Вы также можете использовать синтаксис вложенного пакета, но это довольно необычно.

Основной вариант использования объектов пакета - это когда вам нужны определения в различных местах внутри вашего пакета, а также за его пределами, когда вы используете API, определенный в пакете. Вот пример:

// file: foo/bar/package.scala

package foo

package object bar {

  // package wide constants:
  def BarVersionString = "1.0"

  // or type aliases
  type StringMap[+T] = Map[String,T]

  // can be used to emulate a package wide import
  // especially useful when wrapping a Java API
  type DateTime = org.joda.time.DateTime

  type JList[T] = java.util.List[T]

  // Define implicits needed to effectively use your API:
  implicit def a2b(a: A): B = // ...

}

Теперь определения внутри этого объекта пакета доступны внутри всего пакета foo.bar . Кроме того, определения импортируются, когда кто-то вне этого пакета импортирует foo.bar ._ .

Таким образом вы можете предотвратить необходимость выполнения клиентом API дополнительных операций импорта для эффективного использования вашей библиотеки - например, в scala-swing вам нужно написать

import swing._
import Swing._

, чтобы иметь все возможности вроде onEDT и неявные преобразования из Tuple2 в Dimension .

125
ответ дан 24 November 2019 в 07:16
поделиться

Хотя ответ Морица полностью соответствует действительности, следует отметить еще одну вещь: объекты пакетов являются объектами. Кроме всего прочего, это означает, что вы можете создавать их из трейтов, используя смешанное наследование. Пример Морица можно записать так

package object bar extends Versioning 
                          with JodaAliases 
                          with JavaAliases {

  // package wide constants:
  override val version = "1.0"

  // or type aliases
  type StringMap[+T] = Map[String,T]

  // Define implicits needed to effectively use your API:
  implicit def a2b(a: A): B = // ...

}

Здесь Versioning - абстрактный признак, который говорит, что объект пакета должен иметь метод "version", а JodaAliases и JavaAliases - конкретные признаки, содержащие удобные псевдонимы типов. Все эти черты могут быть повторно использованы многими различными объектами пакетов.

56
ответ дан 24 November 2019 в 07:16
поделиться
7
ответ дан 24 November 2019 в 07:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: