2011-02-17 22 views
7

En Java, Scala o, en general, cualquier lenguaje JVM, hay un conjunto de paquetes importados de manera predeterminada. Java, por ejemplo, importa automáticamente java.lang, no necesita hacerlo en su archivo de código Java.Agregar importaciones predeterminadas de paquetes

Ahora no sé qué componente se encarga de esto exactamente (¿el compilador? ¿La JVM?), Pero ¿hay alguna forma de tener paquetes adicionales o incluso clases importadas por defecto?

Supongamos que tiene un paquete que define un conjunto de funciones de utilidad que utiliza en su proyecto (un ejemplo podría ser scala.math en Scala), sería genial si pudiera saltarse la importación en cada clase relacionada con matemáticas.

+0

"sería genial si pudieras saltear la importación". ¿Por qué? Los IDE modernos tienen autocompletado y funciones para agregar importaciones según sea necesario. Además, las importaciones están destinadas principalmente a documentar el código para otros programadores. Si faltan las importaciones, ¿cómo se supone que el programador debe saber que utiliza 3ra clase arty? –

+1

Su último punto, en mi opinión, debe ser una decisión tomada por el autor del proyecto. Podrías escribir libros sobre ese tema, así que me gustaría dejarlo a un lado aquí. Acerca de su primer punto, cierto, cualquier IDE de Java moderno puede resolver automáticamente un nombre de clase y agregar una importación. Entonces, esto podría ser un problema relacionado con Scala solamente. En Scala (2.8), puede tener "objetos de paquete" que pueden definir campos y métodos en un alcance de paquete. Las hace visibles como si estuvieran definidas en la clase en la que está trabajando al importar el paquete (usando el comodín). No IDE lo admite en este momento por lo que sé. – pdinklag

+0

@AndrewThompson, obstáculo repetitivo para mis ojos = ineficiencia. – Pacerier

Respuesta

12

Scala, a partir de 2.8, tiene objetos de paquete, los contenidos de los cuales se importan automáticamente en cada archivo del paquete. Crear un archivo llamado package.scala en el directorio de nivel superior del paquete (por ejemplo, x/y/z/mypackage), y poner en él

package x.y.z 

package object mypackage { 
    ... 
} 

Entonces, cualquier definición dentro del objeto de paquete se importa automáticamente (es decir, no se necesita ninguna instrucción de importación) en cualquier archivo del paquete xyzmypackage

Puede echar un vistazo a las fuentes de Scala - hacer un encontrar dir -name paquete.scala - hay un montón de ellos, el más alto que define las importaciones implícitas para la scala paquete en sí, que se importan automáticamente en cada archivo fuente scala.

+0

Buen punto. Para cualquier código dentro de un paquete dado, esta es una buena solución. +1 – VonC

+2

@VonC Decir +1 es agradable, pero en realidad la respuesta sería mucho mejor. :-) –

+0

Esto funciona, siempre y cuando trabaje en un solo paquete, ya estoy haciendo uso de esto. Sin embargo, generalmente trabajas con árboles de paquetes. Desafortunadamente, los objetos del paquete no se pueden heredar y las definiciones dentro de un objeto del paquete no afectan a ningún subpaquete. Eso me permitiría definir un objeto de paquete para el paquete raíz y todo estaría bien. Espero que esto sea posible en el futuro. – pdinklag

1

En Java no hay forma de hacerlo.

+2

+1 ... (y gracias a Dios que no!) –

+0

Entiendo que esto es comprensibilidad vs eficiencia de codificación, y que la filosofía de Java trata de mantener una buena comprensión del código (que, IMO, falla en varios formas, pero ese no es el tema que nos ocupa), pero para mi proyecto elegí la eficiencia de codificación (que también es la razón por la que prefiero Scala en lugar de Java), y una característica como esta me facilitaría mucho la vida. Se supone que debes rellenar las funciones en clases apropiadamente nombradas, y la recompensa por hacerlo es tener que importar montones de paquetes y clases donde sea que se necesiten, no demasiado agradable. – pdinklag

+0

@pdinklag Por favor vea mi respuesta; Scala tiene la función que estás buscando. –

11

Jim Balter menciones en his answer (vaya upvote que) la Scala 2,8 package object.

Cualquier tipo de definición que pueda poner dentro de una clase, también puede colocarla en el nivel superior de un paquete. Si tiene algún método de ayuda que le gustaría tener en alcance para un paquete completo, continúe y póngalo en el nivel superior del paquete.

Para hacerlo, coloque las definiciones en un objeto de paquete. Cada paquete tiene permitido tener un objeto de paquete

Scala tiene realmente su propio scala package object.
Ver "Where to put package objects".

El objeto del paquete puede resolver el problema de importación explícita para un paquete determinado, pero no para ningún paquete.
Su current limitations include:

  • En primer lugar, no se puede definir o heredar métodos sobrecargados de objetos de paquete.
  • En segundo lugar, no puede definir ni heredar un miembro en un objeto de paquete que también sea el nombre de una clase u objeto de nivel superior en el mismo paquete.

Esperamos que una futura versión de Scala elimine estas restricciones.


Respuesta original:

En el lado Scala, una pregunta como "should Scala import scala.collection.JavaConversions._ by default?" muestra que no se puede simplemente añadir las importaciones por defecto como usuario Scala.
Tiene que ser compatible con el idioma.

Por cierto, la conclusión fue:

Desde una perspectiva experta Scala: Vamos a mantener las cosas simples y limitar los implícitos que se importan de manera predeterminada al mínimo absoluto.
Heiko Seeberger


Raphael hace comentarios sin embargo:

Creo que se puede escribir su propio plug-in compilador para añadir algunos paquetes?

Y por supuesto, esto Scala article describe how to extend the Scala compiler.
Pero con el material adicional que soporta son:

  • Es posible añadir una fase para el compilador, lo que añade comprobaciones adicionales o reescrituras de árboles adicionales que se aplican después de la comprobación de tipos ha terminado.
  • Puede indicarle a un compilador que comprueba la información acerca de una anotación que se debe aplicar a los tipos.

Así que incluso con una reescritura de árboles (incluyendo las importaciones adicionales), no estoy seguro de dicha reescritura se llevaría a cabo a tiempo para los tipos y funciones (referenciados por las importaciones implícitos que está pidiendo) puede ser correctamente analizado.
Pero tal vez el Scala Compiler Corner tiene más ideas sobre eso.

+0

Supongo que podría escribir su propio plugin de compilador para agregar algunos paquetes? – Raphael

+0

Las cosas han cambiado en Scala 2.8; ver mi respuesta –

4

La importación por defecto de todas las clases de java.lang se especifica en el Java language Specification (7.5.5)

Todos los demás clases tienen que ser de importación con la declaración de importación.