trait - ¿Cómo se define un var/val local en el constructor primario en Scala?
what is a case class in scala (4)
Algunos debates sobre este tema, incluidos los comentarios de Martin Odersky, están here
En Scala, el constructor primario de una clase no tiene cuerpo explícito, pero se define implícitamente desde el cuerpo de la clase. ¿Cómo, entonces, uno distingue entre los campos y los valores locales (es decir, los valores locales para el método constructor)?
Por ejemplo, tome el siguiente fragmento de código, una forma modificada de algún código de muestra de "Programación en Scala":
class R(n: Int, d: Int) {
private val g = myfunc
val x = n / g
val y = d / g
}
Según entiendo, esto generará una clase con tres campos: una "g" privada y una "x" e "y" pública. Sin embargo, el valor de g se usa solo para el cálculo de los campos xey, y no tiene ningún significado más allá del alcance del constructor.
Entonces, en este ejemplo (ciertamente artificial), ¿cómo se puede definir valores locales para este constructor?
Hay algunas maneras de hacer eso. Puede declarar tales variables temporales dentro de definiciones privadas, para usarlas durante el tiempo de construcción. Puede usar variables temporales dentro de bloques que devuelven expresiones (como en la respuesta de Alaz). O, finalmente, puede usar tales variables dentro de constructores alternativos.
De manera similar a los constructores alternativos, también podría definirlos dentro del método "aplicar" del compañero del objeto.
Lo que no puedes hacer es declarar un campo como "temporal".
Tenga en cuenta también que cualquier parámetro recibido por el constructor primario también es un campo. Si no desea que dichos parámetros se conviertan en campos y no desea exponer los campos reales en un constructor, la solución habitual es hacer privado el constructor primario, con los campos reales, y usar un constructor alternativo o un object-companion''s apply () como el constructor "principal" efectivo.
Otra opción que tenemos es hacer que el constructor de objetos primario sea privado y usar el método de aplicación de un objeto complementario como constructor. Si aplicamos (el juego de palabras no está destinado) este enfoque para su ejemplo se verá así:
class R private (val x: Int, val y: Int);
object R {
def apply(n: Int, d: Int): R = {
val g = myfunc;
new R(n / g, d / g);
}
}
Para crear una instancia R en lugar de:
val r = new R(1, 2);
escribir:
val r = R(1, 2);
Esto es un poco detallado, pero podría ser peor, creo :). Esperemos que los vals privados [este] sean tratados como variables temporales en versiones futuras de Scala. El mismo Martin insinuó eso.
P.ej
class R(n: Int, d: Int) {
val (x, y) = {
val g = myfunc
(n/g, d/g)
}
}