web-dev-qa-db-fra.com

Les paramètres du constructeur scala) sont-ils définis par défaut sur une valeur privée?

J'ai essayé:

class Foo(bar: Int)

contre:

class Foo(private val bar: Int)

et ils semblent se comporter de la même manière même si je ne trouvais nulle part où dire que (bar: Int) se développe en (private val bar: Int) donc ma question est, sont-ils identiques/similaires?

Sur une note de côté, j'ai essayé d'utiliser -Xprint:typer sur ces codes et ils produisent le même code, à l’exception d’une ligne supplémentaire dans la seconde. 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>();
    ()
  }
}
..
118
none

bar: Int

C'est à peine un paramètre constructeur. Si cette variable n'est utilisée que par le constructeur, elle y reste. Aucun champ n'est généré. Sinon, le champ private val bar Est créé et la valeur du paramètre bar lui est attribué. Aucun getter n'est créé.

private val bar: Int

Cette déclaration de paramètre créera un champ private val bar Avec un getter privé. Ce comportement est le même que ci-dessus, peu importe si le paramètre a été utilisé à côté du constructeur (par exemple, dans toString() ou non).

val bar: Int

Comme ci-dessus mais le getter de type Scala est public

bar: Int Dans les classes de cas

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

167
Tomasz Nurkiewicz

Dans le premier cas, bar n'est qu'un paramètre de constructeur. Puisque le constructeur principal est le contenu de la classe elle-même, il est accessible dans celle-ci, mais uniquement à partir de cette instance même. Donc, cela équivaut presque à:

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

D'autre part, dans le second cas, bar est un champ privé normal , de sorte qu'il est accessible à cette instance et autres instances de Foo. Par exemple, cela compile bien:

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

Et court:

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

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

Mais cela ne veut pas:

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