122 votes

Les paramètres du constructeur scala sont-ils définis par défaut sur private val?

J'ai essayé:

class Foo(bar: Int)

vs:

class Foo(private val bar: Int)

et ils semblent se comporter de la même, bien que je ne pouvais pas trouver n'importe où en disant qu' (bar: Int) s'étend à d' (private val bar: Int) donc ma question est, sont-ils identiques ou semblables?

Sur une note de côté, j'ai essayé d'utiliser -Xprint:typer sur ces morceaux de code et ils produire le même code, sauf pour une ligne supplémentaire dans le second. Comment puis-je lire cette ligne supplémentaire?

..
class Foo extends scala.AnyRef {
  <paramaccessor> private[this] val bar: Int = _;
  def <init>(bar: Int): this.Foo = {
    Foo.super.<init>();
    ()
  }
}
..


..
class Foo extends scala.AnyRef {
  <paramaccessor> private[this] val bar: Int = _;
  <stable> <accessor> <paramaccessor> private def bar: Int = Foo.this.bar;
  def <init>(bar: Int): this.Foo = {
    Foo.super.<init>();
    ()
  }
}
..

171voto

Tomasz Nurkiewicz Points 140462

bar: Int

C'est à peine un paramètre du constructeur. Si cette variable n'est pas utilisé n'importe où sauf le constructeur, il y reste. Aucun champ n'est généré. Sinon, private val bar champ est créé et la valeur de bar paramètre est affecté. Pas de getter est créé.

private val bar: Int

La déclaration de paramètre permettra de créer private val bar domaine privé de lecture. Ce comportement est le même que ci-dessus, peu importe si le paramètre a été utilisé à côté du constructeur (par exemple, en toString() ou pas).

val bar: Int

Même que ci-dessus mais Scala-comme getter est public

bar: Int dans le cas des classes

Lorsque les classes sont impliquées, par défaut de chaque paramètre a val modificateur.

91voto

gourlaysama Points 5137

Dans le premier cas, bar n'est qu'un paramètre du constructeur. Depuis le principal constructeur est le contenu de la classe elle-même, elle est accessible, mais seulement à partir de cette instance. Donc, il est presque l'équivalent de:

class Foo(private[this] val bar:Int)

En revanche, dans le second cas bar est normal champ privé, de sorte qu'il est accessible à cette instance et les autres instances de Foo. Par exemple, cette compile fine:

class Foo(private val bar: Int) {
  def otherBar(f: Foo) {
    println(f.bar) // access bar of another foo
  }
}

Et s'exécute:

scala> val a = new Foo(1)
a: Foo = Foo@7a99d0af

scala> a.otherBar(new Foo(3))
3

Mais ce n'est pas:

class Foo(bar: Int) {
  def otherBar(f: Foo) {
    println(f.bar) // error! cannot access bar of another foo
  }
}

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