2011-02-13 20 views
9

Una pequeña cuestión de esperar con una respuesta pequeña:colocador Anulación de var

Tengo una var en mi clase que necesita para desencadenar algún tipo de actualización cada vez que se establece. Sé que un var recibe implícitamente dos métodos, un getter y un setter. ¿Es posible anular de alguna manera el método setter para asegurarse de que se active la actualización, sin obtener recursividad? Me refiero a

def a_=(x: Any) = { a = x; update } 

Probablemente será una recursión infinita, ¿verdad?

El var solo se establece fuera de la clase y solo se lee dentro de la clase, quizás eso ayude.

Gracias por escuchar.

+0

¿Puede utilizar otra var como proxy para a? Léalo en el getter for a, configure en setter for a (y llame a 'update'), y el mundo exterior no puede notar la diferencia. –

Respuesta

4

Su código nunca será una recursión infinita porque no se compilará. Debido a la creación implícita de un Getter y un Setter por el compilador, no puede crear dichos métodos dos veces. No sé si hay una razón por la cual el compilador no comprueba si existe un Getter o un Setter y solo si no existen tales métodos crea uno.

Puede evitar este problema cambiando el nombre de la variable privada:

class X(private var _i: Int) { 
    def i = _i 
    def i_=(i: Int) { 
    println(i) 
    _i = i 
    } 
} 

Estos métodos tienen la misma firma que los métodos generados por el compilador.

Si el método update sólo ha llamado una vez que se puede hacer esto en el interior del objeto acompañante:

object X { 
    def apply(i: Int) = { 
    update 
    new X(i) 
    } 
} 
class X(i: Int) 

¿Existe una razón por la que no prefiere un objeto inmutable? Si no, puede copiar el anterior y establecer un nuevo valor al mismo tiempo:

case class X(i: Int, j: Int) 
val x1 = X(3, 6) 
val x2 = x1.copy(i = 1) // x2 = X(1,6) 
+2

No, necesito un estado mutable aquí, es un miembro 'var' de un componente swing. Probablemente vaya por el método proxy aquí, la única solución que puedo ver. Pero es tan ... poco elegante. Hay una razón por la que elegí Scala en lugar de Java. Pero gracias por la entrada. – Lanbo

+0

@ Scán: si se trata de una 'var' de un componente Swing, entonces presumiblemente está creando una clase secundaria, que puede anular los métodos getter y setter del padre; luego use 'super.i _ = (...)' para hacer la configuración en la clase hija. –

+0

@Rex Kerr - No, es un estado para mi hijo, la razón por la que utilicé una clase para niños, para tener este estado. Tal vez esto puede ser incluido de alguna manera en la versión futura del lenguaje scala? – Lanbo