96 votes

Objets d'emballage

Quels sont les objets de package, pas tellement le concept, mais leur utilisation?

J'ai essayé de trouver un travail et la seule forme j'ai eu à travailler a été comme suit:

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)
        }
    }
}

Les Observations que j'ai faites jusqu'à présent sont:

package object _root_ { ... }

est rejeté (ce qui est raisonnable),

package object x.y { ... }

est également rejetée.

Il semble que l'objet d'un package doit être déclarée dans l'immédiat package parent et, s'écrit comme ci-dessus, le corset délimité par paquet formulaire de déclaration est nécessaire.

Sont-ils en commun? Si oui, comment?

134voto

Moritz Points 9149

Normalement vous devriez mettre votre paquet d'objet dans un fichier séparé appelé package.scala dans le package qui correspond à. Vous pouvez également utiliser le imbriquée paquet de syntaxe, mais qui est assez inhabituel.

Les principaux cas d'utilisation pour les objets de package, c'est quand vous avez besoin de définitions dans divers endroits à l'intérieur de votre colis ainsi que l'extérieur de l'emballage lorsque vous utilisez l'API défini par le paquet. Voici un exemple:

// 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 = // ...

}

Maintenant, les définitions de l'intérieur que de l'objet package sont disponibles à l'intérieur de l'ensemble du paquet, foo.bar. En outre, les définitions de l'importation lorsque quelqu'un de l'extérieur de l'ensemble des importations foo.bar._.

De cette façon, vous pouvez éviter d'exiger de l'API client d'émettre des importations supplémentaires pour l'utilisation de votre bibliothèque de manière efficace - par exemple en scala-swing, vous devez écrire

import swing._
import Swing._

pour avoir tous les bienfaits comme onEDT et les conversions implicites de Tuple2 de Dimension.

58voto

Dave Griffith Points 12923

Alors que Moritz réponse est sur place, une autre chose à noter est que les objets de package sont des objets. Entre autres choses, cela signifie que vous pouvez construire à partir de traits, à l'aide du mélange sur l'héritage. Moritz exemple peut être écrite comme

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 = // ...

}

Ici, la gestion des versions est un résumé de trait, qui dit que l'objet de package doit avoir une "version" de la méthode, tout en JodaAliases et JavaAliases sont en béton traits contenant pratique de type alias. Tous ces traits peuvent être réutilisés par de nombreux objets de package.

7voto

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X