56 votes

++ opérateur en Scala

Est-il une raison pour Scala pas en charge l' ++ opérateur d'incrémentation types primitifs par défaut? Par exemple, vous ne pouvez pas écrire:

var i=0
i++

Merci

36voto

pkaeding Points 12935

Je suppose que ça a été omis, car il ne fonctionne que pour les variables mutables, et il ne serait pas logique pour des valeurs inaltérables. Peut-être qu'il a été décidé que l' ++ opérateur ne crie pas d'affectation, de sorte dont il peut conduire à des erreurs quant à savoir si ou non vous êtes à la mutation de la variable.

J'ai l'impression que quelque chose comme cela est sécuritaire de le faire (sur une seule ligne):

i++

mais ce serait une mauvaise pratique (dans n'importe quelle langue):

var x = i++

Vous ne voulez pas mélanger les instructions d'affectation et effets secondaires/mutation.

33voto

Daniel C. Sobral Points 159554

J'aime Craig's réponse, mais je pense que le point doit être plus fort.

  1. Il n'existe pas de "primitives" -- si Int peuvent le faire, si un utilisateur fait- Complex (par exemple).

  2. Utilisation de base de l' ++ serait comme ceci:

    var x = 1 // or Complex(1, 0)

    x++

  3. Comment mettre en oeuvre ++ dans la classe Complex? En supposant que, comme Int, l'objet est immuable, puis l' ++ méthode doit renvoyer un nouvel objet, mais ce nouvel objet doit être attribué.

Il aurait besoin d'une nouvelle fonctionnalité du langage. Par exemple, disons que nous avons créer un assign mot-clé. La signature d'un type de aurait besoin d'être changé, pour indiquer qu' ++ n'est pas le retour d'un Complex, mais l'attribution à quelque domaine que ce soit, est tenue de l'objet présent. En Scala esprit de ne pas empiéter dans la programmation de l'espace de noms, disons-nous faire en préfixant le type avec @.

Alors qu'il pourrait être comme ceci:

case class Complex(real: Double = 0, imaginary: Double = 0) {
  def ++: @Complex = {
    assign copy(real = real + 1)
    // instead of return copy(real = real + 1)
}

Le problème suivant est que postfix opérateurs sucer avec Scala règles. Par exemple:

def inc(x: Int) = {
  x++
  x
}

En raison de la Scala de règles, c'est la même chose que:

def inc(x: Int) = { x ++ x }

Ce qui n'était pas le but. Maintenant, Scala privilèges d'un style fluide: obj method param method param method param .... Qui se mélange bien C++/Java traditionnel de la syntaxe de l' object method parameter avec la programmation fonctionnelle concept de pipeline d'une entrée par le biais de multiples fonctions pour obtenir le résultat final. Ce style a été récemment appelé "fluent interfaces".

Le problème est que, en privilégiant ce style, il paralyse les opérateurs de suffixe (et un préfixe, mais Scala a à peine de toute façon). Donc, à la fin, Scala aurait à faire de grands changements, et il serait capable de se mesurer à l'élégance de C/Java d'incrémentation et de décrémentation les opérateurs de toute façon-sauf si il a vraiment quitté le genre de chose qu'il ne l'appui.

20voto

Craig P. Motlin Points 11814

En Scala, ++ est une méthode valable, et aucune méthode implique la cession. Seulement = peut le faire.

Plus de réponse, c'est que les langages comme C++ et Java traiter ++ spécialement, et Scala friandises = spécialement, et d'une manière incohérente.

En Scala, lorsque vous écrivez i += 1 le compilateur recherche d'abord une méthode appelée += sur l'Int. Il n'y est pas alors, la prochaine il ne c'est magique sur = et essaie de compiler la ligne comme si elle lisait i = i + 1. Si vous écrivez i++ alors Scala va appeler la méthode ++ sur i et affecter le résultat à... rien du tout. Parce que seulement = moyen d'affectation. Vous pouvez écrire i ++= 1 mais ce genre de défaites le but.

Le fait que la Scala prend en charge les noms de méthode comme += est déjà controversée et certains pensent que c'est la surcharge d'opérateur. Ils pourraient avoir ajouté un comportement particulier pour ++ mais ce ne serait alors plus être valide, le nom de la méthode (comme =) et il serait plus qu'une chose à se rappeler.

12voto

Rex Kerr Points 94401

Je pense que le raisonnement est en partie qu' +=1 n'est plus un seul personnage, et ++ est utilisé assez fortement dans les collections de code pour la concaténation. Aussi, il garde le code plus propre.

Aussi, Scala encourage immuable variables, et ++ est intrinsèquement une mutation de l'opération. Si vous avez besoin d' +=, au moins, vous pouvez forcer tous vos mutations de passer par une commune de la procédure d'affectation (par exemple, def a_=).

2voto

Rich Oliver Points 1942

Les raisons pour ne pas l'utiliser dans les classiques du C++ ont déjà été donnés par d'autres. Mais ce n'est aucune raison de ne pas l'utiliser en tant que valeur de retour de la méthode. - Je inclure dans mon top niveau, avec quelques autres méthodes utiles, qui ne sont pas dans la bibliothèque standard au moment de l'écriture:

implicit class RichInt2(n: Int) extends Unchanged[Int] {
  override def unchanged: Int = n
  def isOdd: Boolean = if (n % 2 == 1) true else false
  def isEven: Boolean = if (n % 2 == 0) true else false
  def ++ : Int = n + 1
  def -- : Int = n - 1
  def ifinc(b: Boolean): Int = if (b) n + 1 else n
  def ifdec(b: Boolean): Int = if (b) n - 1 else n
}

trait Unchanged[T {
  def unchanged: T 
  def ifes(b: Boolean, f: T => T): T = if (b) f(unchanged) else unchanged
}

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