60 votes

Comment définissez-vous une var / val locale dans le constructeur primaire de Scala?

En Scala, une classe du primaire constructeur n'a pas explicite du corps, mais est définie implicitement dans le corps de la classe. Alors, comment fait-on la distinction entre les champs et les valeurs locales (c'est à dire les valeurs locales à la méthode constructeur)?

Par exemple, prenez le fragment de code suivant, une modification de la forme d'un exemple de code à partir de "Programming in Scala":

class R(n: Int, d: Int) {
   private val g = myfunc
   val x = n / g
   val y = d / g
}

Ma compréhension est que cela permet de générer une classe avec trois champs: un privé "g", et le public "x" et "y". Toutefois, la valeur g est utilisé uniquement pour le calcul des champs x et y, et n'a pas de sens au-delà de l'constructeur de portée.

Donc, dans ce (certes artificielle), par exemple, comment allez-vous définir les valeurs locales pour ce constructeur?

37voto

Alexander Azarov Points 6630

Par exemple

 class R(n: Int, d: Int) {
  val (x, y) = {
    val g = myfunc
    (n/g, d/g)
  }
}
 

16voto

Daniel C. Sobral Points 159554

Il ya quelques façons de le faire. Vous pouvez déclarer ces variables temporaires à l'intérieur de privé définitions, pour être utilisé pendant le temps de la construction. Vous pouvez utiliser des variables temporaires à l'intérieur des blocs qui le retour des expressions (comme dans Alaz de réponse). Ou, enfin, vous pouvez utiliser ces variables à l'intérieur d'alterner les constructeurs.

D'une manière similaire à l'autre des constructeurs, vous pouvez également définir à l'intérieur de l'objet-d'un compagnon "appliquer" la méthode.

Ce que vous ne pouvez pas faire est de déclarer un champ "temporaire".

Notez également que toutes les paramètre reçu par le principal constructeur est un domaine également. Si vous ne voulez pas de tels paramètres à devenir des champs, et ne voulez pas exposer la réelle champs dans un constructeur, la solution habituelle est de rendre le primaire constructeur privé, avec les champs, et utiliser un autre constructeur ou d'un objet-l'accompagnement de l'appliquer() comme la "primaire" du constructeur.

13voto

Maxim Vladimirsky Points 581

Une autre option que nous avons est de faire de l'objet principal constructeur privé et l'utilisation d'un compagnon de l'objet d'appliquer la méthode en tant que constructeur. Si l'on applique (le jeu de mots n'est pas prévu) cette approche à votre exemple, il ressemblera à ceci:

class R private (val x: Int, val y: Int);

object R {
  def apply(n: Int, d: Int): R = {
    val g = myfunc;
    new R(n / g, d / g);
  }
}

Pour créer une R exemple, au lieu de:

val r = new R(1, 2);

écrire:

val r = R(1, 2);

C'est un peu verbeux, mais ça pourrait être pire, je pense :). Espérons que privé[ce] vals seront traités comme des variables temporaires dans les futures versions de la Scala. Martin lui-même laissé entendre qu'.

6voto

Pavel Feldman Points 2140

Quelques discussions sur ce sujet, y compris les commentaires de Martin Odersky, sont ici

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