Delegación de Kotlin a expresión en lugar de reference fija

Supongamos que tengo una especificación muy compleja definida como una interfaz:

interface Spec { fun sayHello() } 

Y una implementación estándar:

 class Impl(private val msg: String) : Spec { override fun sayHello() { println(msg) } } 

Supongamos ahora que quiero crear una class que implemente esta especificación y delegue en una implementación, pero el object delegado exacto se puede modificar a lo largo de la vida del object. Aquí hay un ejemplo:

 class Derived(var target: Spec) : Spec by target 

El problema con el ejemplo anterior es que el target argumento constructor se establece como el object delegado cuando se llama al constructor. La class accede directamente al delegado en lugar de realizar un acceso a la propiedad. (Esto ha sido confirmado mirando el bytecode producido por Kotlin).

Por lo tanto, incluso si el target la propiedad se modifica después de que se construye la class, el delegado no cambia.

¿Alguien puede proporcionar un método para realizar esta delegación en Kotlin sin tener que escribir todos los methods?

Una solución ideal también permitiría delegar en algo tan general como una lambda u otra expresión que sería evaluada y utilizada como delegado cada vez que el delegado se necesita durante toda la vida del object.

En este momento no hay forma de hacer eso. Ver el número KT-5870 de Kotlin

Currenlty Kotlin evalúa expresión para delegado en el inicializador de class

Puede agregar un nivel de direccionamiento indirecto:

 class Holder(var impl: Spec) : Spec { override fun sayHello() = impl.sayHello() } class Derived(target: Spec, private val holder: Holder = Holder(target)) : Spec by holder { fun changeTarget(newTarget: Spec) { holder.impl = newTarget } } 

Lamentablemente, el holder debe ser un parámetro de constructor para poder usarlo con la construcción de delegación (como en el caso de Kotlin v1.0), por lo que complica el constructor principal.

  • Uso de Kotlin y Firebase para desencadenar un sendEmailVerification con onAuthStateChanged callback
  • Usar Kotlin en un module de biblioteca sin usarlo en el module de la aplicación
  • Consulte el tipo genérico en Kotlin
  • Convierte XML a Anko DSL
  • Un equivalente de text para la imageView
  • Manera idiomática de manejar lists anulables o vacías en Kotlin
  • No se puede iniciar el animador en una vista separada
  • Kotlin y WebSockets
  • Cómo crear callbacks de funciones anidadas como anko - syntax DSL Kotlin
  • Error de data binding en Android Spinner
  • El proyecto kotlin no se puede build en gradle (no se puede encontrar la reference)