crear - scala class constructor
¿Los parámetros de scala constructor están por defecto en val privado? (2)
He estado intentando:
class Foo(bar: Int)
vs:
class Foo(private val bar: Int)
y parecen comportarse igual aunque no pude encontrar en ninguna parte diciendo que (bar: Int)
expande a (private val bar: Int)
así que mi pregunta es, ¿son estos idénticos / similares?
En una nota lateral, he estado tratando de usar -Xprint:typer
en estas piezas de código y producen el mismo código a excepción de una línea adicional en la segunda. ¿Cómo leo esa línea adicional?
..
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>();
()
}
}
..
En el primer caso, la bar
es solo un parámetro de constructor. Como el constructor principal es el contenido de la clase en sí, se puede acceder a él, pero solo desde esta misma instancia. Entonces es casi equivalente a:
class Foo(private[this] val bar:Int)
Por otro lado, en el segundo caso, la bar
es un campo privado normal , por lo que es accesible para esta instancia y otras instancias de Foo
. Por ejemplo, esto compila bien:
class Foo(private val bar: Int) {
def otherBar(f: Foo) {
println(f.bar) // access bar of another foo
}
}
Y corre:
scala> val a = new Foo(1)
a: Foo = Foo@7a99d0af
scala> a.otherBar(new Foo(3))
3
Pero esto no:
class Foo(bar: Int) {
def otherBar(f: Foo) {
println(f.bar) // error! cannot access bar of another foo
}
}
bar: Int
Esto es apenas un parámetro constructor. Si esta variable no se usa en ningún lugar excepto el constructor, permanece allí. No se genera ningún campo De lo contrario private val bar
se crea un campo de private val bar
y se le asigna un valor de parámetro de bar
. No se crea getter.
private val bar: Int
Dicha declaración de parámetro creará private val bar
campo de private val bar
privada con getter privado. Este comportamiento es el mismo que el anterior, independientemente de si el parámetro se utilizó junto al constructor (por ejemplo, en toString()
o no).
val bar: Int
Igual que el anterior pero el getter tipo Scala es público
bar: Int
en caso de clases
Cuando se trata de clases de casos, por defecto cada parámetro tiene un modificador de val
.