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>();
()
}
}
..
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
.
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
}
}