73 votes

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

En revenant à Scala après avoir écrit un peu de 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 type doivent vivre à l'intérieur d'une classe ou d'un objet - elles ne sont pas des "citoyens de première classe" comme elles le sont en Haskell. Si j'essaye de définir un type en dehors d'une classe ou d'un objet, j'obtiens un message du compilateur expected class or object definition .

Mon problème est alors de savoir comment utiliser ces types dans plusieurs classes et objets d'un même paquet ? Ce que j'ai fait jusqu'à présent est assez moche :

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

Et ensuite dans un autre fichier de classe :

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

Existe-t-il une façon plus agréable de procéder ? Et, à propos, les gourous de Scala pensent-ils que c'est une bonne ou une mauvaise chose que les types ne puissent être définis qu'à l'intérieur de classes/objets ?

9 votes

Pourquoi pas ? import utils.RestfulTypes._ ?

71voto

Ray Toal Points 35382

Will objets du paquet travailler pour vous ?

Extrait de l'article :

Jusqu'à la version 2.8, les seules choses que vous pouviez mettre dans un paquet étaient les classes, les traits et les objets autonomes. Ce sont de loin les définitions les plus courantes qui sont placées au niveau supérieur d'un paquet, mais Scala 2.8 ne vous limite pas à celles-ci. Tout type de définition que vous pouvez placer dans une classe peut également être placé au niveau supérieur d'un paquet. Si vous disposez d'une méthode d'aide que vous souhaitez voir figurer dans le champ d'application d'un paquetage entier, allez-y et placez-la au niveau supérieur du paquetage. Pour ce faire, vous placez les définitions dans un objet package. Chaque paquet est autorisé à avoir un objet package. Toutes les définitions placées dans un objet package sont considérées comme des membres du package lui-même.

El paquet objet scala possède déjà de nombreux types et valeurs, je pense donc que vous pouvez utiliser la même technique pour vos propres types.

11voto

Kim Stebel Points 22873

Je ne suis pas sûr de ce qui constitue la gentillesse dans ce cas, mais voici deux options :

Utilisation d'un trait : ( Le modèle de trait désintéressé de Scala )

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

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

Vous pouvez également importer les membres de l'objet, en l'utilisant comme un paquet :

import util.RestfulTypes._

1 votes

@agilesteel : le lien ne devrait pas être en premier puisqu'il n'appartient qu'à la première option, merci de ne pas changer le sens de ma réponse en éditant.

0 votes

Merci, le modèle de trait altruiste est très cool. Je me rends compte que j'ai vu plusieurs frameworks et outils Scala l'utiliser, mais je n'avais pas réalisé ce que c'était. Merci encore pour la réponse.

0 votes

@Kim : désolé, ça n'arrivera plus.

7voto

firephil Points 163

Vous pouvez utiliser un objet package et y placer la déclaration de type. Lorsque vous importerez ce paquet, la définition de type sera disponible.

Un exemple :

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

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

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

on peut y accéder avec mainType.mine quand on importe "package".

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

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