¿Qué son los objetos de paquete, no tanto el concepto como su uso?
Intenté que funcionara un ejemplo y la única forma en que pude trabajar fue la siguiente:
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)
}
}
}
Las observaciones que he hecho hasta ahora son:
package object _root_ { ... }
no está permitido (lo cual es razonable),
package object x.y { ... }
tampoco está permitido.
Parece que un objeto de paquete debe declararse en el paquete padre inmediato y, si se escribe como se indicó anteriormente, se requiere el formulario de declaración de paquete delimitado por llaves.
¿Son de uso común? ¿Si es así, cómo?
Respuestas:
Normalmente, pondría su objeto de paquete en un archivo separado llamado
package.scala
en el paquete al que corresponde. También puede utilizar la sintaxis del paquete anidado, pero eso es bastante inusual.El caso de uso principal para los objetos de paquete es cuando necesita definiciones en varios lugares dentro de su paquete, así como fuera del paquete cuando usa la API definida por el paquete. Aquí hay un ejemplo:
Ahora las definiciones dentro de ese objeto de paquete están disponibles dentro de todo el paquete
foo.bar
. Además, las definiciones se importan cuando alguien ajeno a ese paquete importafoo.bar._
.De esta manera, puede evitar que el cliente API emita importaciones adicionales para usar su biblioteca de manera efectiva; por ejemplo, en scala-swing necesita escribir
para tener todas las bondades
onEDT
y conversiones implícitas deTuple2
aDimension
.fuente
org
o decom
nivel superior con su objeto de paquete si desea que pertenezca a su propio paquete raíz, por ejemploorg.foo
. Descubrí que permitir que la definición esté directamente debajo del paquete del que debería ser parte, habría sido una interfaz de API de lenguaje un poco más adecuada.Si bien la respuesta de Moritz es acertada, una cosa adicional a tener en cuenta es que los objetos de paquete son objetos. Entre otras cosas, esto significa que puede construirlos a partir de rasgos, usando herencia mixta. El ejemplo de Moritz podría escribirse como
Aquí el control de versiones es un rasgo abstracto, que dice que el objeto del paquete debe tener un método de "versión", mientras que JodaAliases y JavaAliases son rasgos concretos que contienen prácticos alias de tipo. Todos estos rasgos pueden ser reutilizados por muchos objetos de paquete diferentes.
fuente
Podría hacer algo peor que ir directamente a la fuente. :)
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
fuente
No es así con Scala 3 , programado para ser lanzado a mediados de 2020, basado en Dotty , como aquí :
fuente