gratis descargar compiler kotlin

descargar - Kotlin: compruebe si se ha inicializado el valor perezoso



kotlin vs scala (3)

¿Hay alguna manera de saber si un valor perezoso se ha inicializado en Kotlin sin inicializarlo en el proceso?

por ejemplo, si tengo un valor perezoso, consultar si es nulo lo instanciaría

val messageBroker: MessageBroker by lazy { MessageBroker() } if (messageBroker == null) { // oops }

Podría potencialmente usar una segunda variable, pero eso parece desordenado.

private var isMessageBrokerInstantiated: Boolean = false val messageBroker: MessageBroker by lazy { isMessageBrokerInstantiated = true MessageBroker() } ... if (!isMessageBrokerInstantiated) { // use case }

¿Hay alguna forma atractiva de determinar esto, como if (Lazy(messageBroker).isInstantiated()) ?

Relacionado (pero no el mismo): ¿Cómo verificar si una variable "lateinit" se ha inicializado?


Desde Kotlin 1.1, puede acceder a un delegado de propiedad directamente utilizando .getDelegate() .

Puede escribir una propiedad de extensión para una referencia de propiedad que compruebe que tiene un delegado Lazy que ya se ha inicializado:

/** * Returns true if a lazy property reference has been initialized, or if the property is not lazy. */ val KProperty0<*>.isLazyInitialized: Boolean get() { if (this !is Lazy<*>) return true // Prevent IllegalAccessException from JVM access check on private properties. val originalAccessLevel = isAccessible isAccessible = true val isLazyInitialized = (getDelegate() as Lazy<*>).isInitialized() // Reset access level. isAccessible = originalAccessLevel return isLazyInitialized }

Luego en el sitio de uso:

val messageBroker: MessageBroker by lazy { MessageBroker() } if (this::messageBroker.isInitialized) { // ... }

Esta solución requiere que kotlin-reflect esté en el classpath. Con Gradle, utilizar
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"

La parte isAccessible = true es necesaria para .getDelegate() , porque de lo contrario no puede acceder al campo privado que almacena la referencia del delegado.


Hay una forma, pero tiene que acceder al objeto delegado que devuelve la lazy {} :

val messageBrokerDelegate = lazy { MessageBroker() } val messageBroker by messageBrokerDelegate if(messageBrokerDelegate.isInitialized()) ...

isInitialized es un método público en la interfaz Lazy<T> , aquí están los docs .


Sobre la base de la solución de teclas de acceso rápido , puede hacer que una propiedad isLazyInitialized (en lugar de una función), sea coherente con la propiedad isInitialized para vars de inicio tardío.

Además, no hay necesidad de manejar el caso nulo.

import kotlin.reflect.KProperty0, import kotlin.reflect.jvm.isAccessible val KProperty0<*>.isLazyInitialized: Boolean get() { // Prevent IllegalAccessException from JVM access check isAccessible = true return (getDelegate() as Lazy<*>).isInitialized() }