web-dev-qa-db-fra.com

Scala mot-clé de type: comment l'utiliser au mieux dans plusieurs classes

Pour en revenir à Scala après un sort écrit Haskell, j'ai commencé à utiliser le mot-clé type pour rendre mes définitions de classe un peu plus lisibles, par exemple:

type RestfulParams = Map[String, String]
def canonicalize(params: RestfulParams): String = { ... }

Le problème que j'ai rencontré est que ces définitions de types doivent vivre à l'intérieur d'une classe ou d'un objet - ce ne sont pas des "citoyens de première classe" comme ils le sont à Haskell. Si j'essaie de définir un type en dehors d'une classe ou d'un objet, j'obtiens un compilateur expected class or object definition.

Mon problème est alors de savoir comment utiliser ces types sur plusieurs classes et objets dans un package? Ce que j'ai fait maintenant semble assez moche:

object RestfulTypes { type RestfulParams = Map[String, String] etc }

Et puis dans un autre fichier de classe:

import utils.{RestfulTypes => RT}
def get(resource: String, params: RT.RestfulParams): String = { ... }

Y a-t-il une meilleure façon de le faire - et incidemment les Scala gourous pensent que c'est une bonne ou une mauvaise chose que les types ne puissent être définis qu'à l'intérieur des classes/objets?

70
Alex Dean

les objets de package fonctionneront-ils pour vous?

De l'article:

Jusqu'à la version 2.8, les seules choses que vous pouviez mettre dans un package étaient les classes, les traits et les objets autonomes. Ce sont de loin les définitions les plus courantes placées au niveau supérieur d'un package, mais Scala 2.8 ne vous limite pas à celles-ci. N'importe quel type de définition que vous pouvez mettre à l'intérieur d'un , vous pouvez également mettre au niveau supérieur d'un package. Si vous avez une méthode d'assistance que vous souhaitez être dans la portée d'un package entier, allez-y et mettez-le directement au niveau supérieur du package. Pour ce faire , vous placez les définitions dans un objet de package. Chaque package est autorisé à avoir un objet de package. Toutes les définitions placées dans un objet de package sont considérées comme membres du package lui-même.

Le package object scala a déjà de nombreux types et valeurs, donc je pense que vous pouvez utiliser la même technique pour vos propres types.

71
Ray Toal

Je ne sais pas ce qui constitue la gentillesse dans ce cas, mais voici deux options:

Utiliser un trait: ( Motif de trait altruiste de Scala )

trait RestfulTypes {
  type Params = Map[String,String]
  //...
}

object MyRestService extends RestService with RestfulTypes { /* ... */ }

Ou importez simplement les membres de l'objet, en l'utilisant efficacement comme un package:

import util.RestfulTypes._
11
Kim Stebel

Youn peut utiliser un objet package et y mettre la déclaration de type. Lorsque vous importez ce package, la définition de type sera disponible.

Un exemple :

//package myType
package object myType {type mine = List[String]}

Notez que l'objet package a le même nom que le package afin d'être utilisable sans préfixe d'objet, c'est-à-dire myType.mine Si vous le nommez avec un nom différent par exemple:

//package myType
package object mainType {type mine = List[String]}

il est accessible avec mainType.mine lorsque vous importez "package"

pour plus d'informations: http://www.scala-lang.org/docu/files/packageobjects/packageobjects.html

7
firephil