variable new properties kotlin didset

properties - new - ¿Hay un análogo didSet/willSet en Kotlin?



public variable in kotlin (1)

Aunque Kotlin no proporciona una solución incorporada de estilo Swift para la observación de cambios de propiedad, puede hacerlo de varias maneras dependiendo de cuál sea su objetivo.

  • Hay un delegado observable(...) (en stdlib) que le permite manejar los cambios de propiedad. Ejemplo de uso:

    var foo: String by Delegates.observable("bar") { property, old, new -> println("$property has changed from $old to $new") }

    Aquí, "bar" es el valor inicial de la propiedad foo , y se llama a la lambda cada vez que se le asigna la propiedad, lo que le permite observar los cambios. También vetoable(...) delegado vetoable(...) que le permite evitar el cambio.

  • Puede usar el configurador personalizado para que una propiedad ejecute código arbitrario antes / después del cambio de valor real:

    var foo: String = "foo" set(value: String) { baz.prepareToDoTheThing() field = value baz.doTheThing() }

    Como señaló @KirillRakhman , esta solución es bastante eficiente ya que no introduce gastos indirectos en llamadas de método y objetos, aunque el código se duplicará en el caso de varias propiedades.

  • En general, puede implementar su propio delegado de propiedad , proporcionando explícitamente el comportamiento de la propiedad en las funciones getValue(...) y setValue(...) .

    Para simplificar su tarea, utilice la clase abstracta ObservableProperty<T> que le permite implementar delegados que observen cambios de propiedad (como observable y vetoable anteriormente). Ejemplo:

    var foo: String by object : ObservableProperty<String>("bar") { override fun beforeChange(property: KProperty<*>, oldValue: String, newValue: String): Boolean { baz.prepareToDoTheThing() return true // return false if you don''t want the change } override fun afterChange(property: KProperty<*>, oldValue: String, newValue: String) { baz.doTheThing() } }

    Para su comodidad, puede escribir una función que crea el objeto delegado:

    fun <T> observing(initialValue: T, willSet: () -> Unit = { }, didSet: () -> Unit = { } ) = object : ObservableProperty<T>(initialValue) { override fun beforeChange(property: KProperty<*>, oldValue: T, newValue: T): Boolean = true.apply { willSet() } override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) = didSet() }

    Luego, simplemente le pasa lambdas como willSet y didSet ( el argumento predeterminado para ellos es { } ). Uso:

    var foo: String by observing("bar", willSet = { baz.prepareToDoTheThing() }, didSet = { baz.doTheThing() }) var baq: String by observing("bar", didSet = { println(baq) })

En cualquier caso, depende de usted asegurarse de que el código que observa los cambios no vuelva a establecer la propiedad, ya que es probable que caiga en una recursión infinita, o bien puede verificarlo en el código de observación ya sea que se llame recursivamente al colocador.

Me encanta esta sintaxis Swift; es muy útil para muchas cosas:

var foo: Bar = Bar() { willSet { baz.prepareToDoTheThing() } didSet { baz.doTheThing() } }

y me encantaría hacer esto en Kotlin. Sin embargo, no puedo encontrar la sintaxis correcta .

¿Hay algo en Kotlin como este?

var foo: Bar = Bar() willSet() { baz.prepareToDoTheThing() } didSet() { baz.doTheThing() }