Todavía estoy aprendiendo sobre Scala, pero una cosa que me pareció interesante es que Scala difumina la línea entre métodos y campos. Por ejemplo, puedo construir una clase como esta ...Propiedades de Scala Pregunta
class MutableNumber(var value: Int)
La clave aquí es que el var en el constructor-argumento permite automáticamente que yo use el campo 'valor' como un captador/definidor en Java.
// use number...
val num = new MutableNumber(5)
num.value = 6
println(num.value)
Si quiero agregar restricciones, puedo hacerlo por el cambio a usar métodos en lugar de la instancia-campos:
// require all mutable numbers to be >= 0
class MutableNumber(private var _value: Int) {
require(_value >= 0)
def value: Int = _value
def value_=(other: Int) {
require(other >=0)
_value = other
}
}
El código del lado del cliente no se rompe desde la API doesn 't change:
// use number...
val num = new MutableNumber(5)
num.value = 6
println(num.value)
Mi cuelgue es con la función de parámetro nombrado que se agregó a Scala-2.8. Si uso named-parameters, mi API cambia y hace rompe la API.
val num = new MutableNumber(value=5) // old API
val num = new MutableNumber(_value=5) // new API
num.value = 6
println(num.value)
¿Hay alguna solución elegante para esto? ¿Cómo debería diseñar mi clase MutableNumber para poder agregar restricciones más adelante sin romper la API?
Gracias!
Interesante! Así que al esconder el constructor obligo a todos a usar el objeto compañero. ¿Qué sucede si quiero hacer que MutableInteger sea una clase de caso?Sé que si coloco 'caso' delante de la definición de clase, Scala crea automáticamente el objeto complementario para mí ... ¿esta solución funcionaría? – shj
Sí, si tiene un objeto complementario explícitamente definido para una clase de caso, los miembros de ese objeto se fusionarán en el generado (y puede anular, si, por ejemplo, desea proporcionar un método 'Companion.apply()' ajustado) pero mantén el autogenerado 'unapply'). –
@shj - No, eso no funcionaría porque las clases de casos suponen un acceso directo (no protegido) a las variables del constructor. Estás haciendo esto porque quieres guardias (en la forma de 'require (_value> = 0)' en este caso). –