2012-06-25 20 views
7

Entiendo que los campos paramétricos (como x en el ejemplo siguiente) se comportan como los campos normales; por lo que se puede hacer referencia a ellos en los métodos:Campos paramétricos de Scala y argumentos del constructor

class Test(val x: Int) { // x is a parametric field 
    override def toString = "Test: " + x; 
} 

Sin embargo, si se le cae la palabra clave val, el código se compila todavía (y mirando y la salida .class, x sigue siendo un miembro de la clase). Entonces me pregunto, ¿cuál es la diferencia entre los campos paramétricos (es decir, val x: Int en el anterior) y los argumentos del constructor (x: Int)?

(Con Java en la parte posterior de la cabeza, me habría esperado que el alcance de un constructor como x a no incluyen un método como toString.)

+0

Creo 'x' aún así estar se convierte en miembro si se hace referencia en al menos 1 método, independientemente de si está o no prefijado con 'val'. – adelbertc

Respuesta

9

Sin la palabra clave val, su código es similar a : class Test (private[this] val x: Int) { ... }. Por lo tanto, x está disponible en toda la clase pero no desde el exterior.

No se menciona en su pregunta, pero también puede ser útil: en un case class, el modificador predeterminado es val. Por lo tanto, case class Test(x: Int) {...} es equivalente a case class (val x: Int) {...}.

+2

Equivalente, menos todas las demás cosas que tiene una 'clase de caso', por supuesto. :-) –

+0

@ DanielC.Sobral En realidad, no lo he precisado porque el error tipográfico que corrigió no era realmente un error tipográfico. ;) – Nicolas

2

Un parámetro constructor se convierte efectivamente en un campo private[this] pero solo si se hace referencia en al menos un método. De lo contrario, no se genera un campo en la clase.

Por ejemplo:

class Foo(i: Int) { 
    println(i) 
} 

convierte

$ javap -private Foo 
Compiled from "Foo.scala" 
public class Foo extends java.lang.Object implements scala.ScalaObject{ 
    public Foo(int); 
} 

Pero

class Bar(i: Int) { 
    def baz = println(i) 
} 

convierte

$ javap -private Bar 
Compiled from "Bar.scala" 
public class Bar extends java.lang.Object implements scala.ScalaObject{ 
    private final int i; 
    public void baz(); 
    public Bar(int); 
} 
Cuestiones relacionadas