O que são objetos de pacote, não tanto o conceito, mas seu uso?
Tentei fazer um exemplo funcionar e a única forma que consegui funcionar foi a seguinte:
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)
}
}
}
As observações que fiz até agora são:
package object _root_ { ... }
não é permitido (o que é razoável),
package object x.y { ... }
também não é permitido.
Parece que um objeto de pacote deve ser declarado no pacote pai imediato e, se escrito como acima, o formulário de declaração de pacote delimitado por chaves é necessário.
Eles são de uso comum? Se sim, como?
Respostas:
Normalmente, você colocaria seu objeto de pacote em um arquivo separado chamado
package.scala
no pacote ao qual ele corresponde. Você também pode usar a sintaxe de pacote aninhado, mas isso é bastante incomum.O principal caso de uso para objetos de pacote é quando você precisa de definições em vários lugares dentro do seu pacote, bem como fora do pacote, ao usar a API definida pelo pacote. Aqui está um exemplo:
Agora, as definições dentro desse objeto de pacote estão disponíveis dentro de todo o pacote
foo.bar
. Além disso, as definições são importadas quando alguém de fora desse pacote importafoo.bar._
.Desta forma, você pode evitar que o cliente API emita importações adicionais para usar sua biblioteca de forma eficaz - por exemplo, no scala-swing, você precisa escrever
ter todas as
onEDT
conversões semelhantes e implícitas de bondade deTuple2
paraDimension
.fonte
org
ou decom
nível superior com o seu objeto de pacote se desejar que ele pertença ao seu próprio pacote raizorg.foo
. Eu acho que permitir que a definição esteja diretamente sob o pacote do qual ela deveria fazer parte - teria sido uma interface API de linguagem um pouco mais adequada.Embora a resposta de Moritz seja correta, uma coisa adicional a ser observada é que os objetos de pacote são objetos. Entre outras coisas, isso significa que você pode construí-los a partir de características, usando a herança combinada. O exemplo de Moritz poderia ser escrito como
Aqui, o controle de versão é uma característica abstrata, que diz que o objeto de pacote deve ter um método de "versão", enquanto JodaAliases e JavaAliases são características concretas contendo apelidos de tipo úteis. Todas essas características podem ser reutilizadas por muitos objetos de pacote diferentes.
fonte
Você poderia fazer pior do que ir direto à fonte. :)
https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk/src/library/scala/package.scala
https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk/src/library/scala/collection/immutable/package.scala
fonte
Não é assim com Scala 3 , programado para ser lançado em meados de 2020, baseado em Dotty , como aqui :
fonte