Skip to content

Instantly share code, notes, and snippets.

@azabost
Created November 30, 2022 12:54
Show Gist options
  • Save azabost/7557855204561070790ce9338cbfb687 to your computer and use it in GitHub Desktop.
Save azabost/7557855204561070790ce9338cbfb687 to your computer and use it in GitHub Desktop.
Kotlin mutable lazy delegate
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
fun <T> mutableLazy(initializer: () -> T) = MutableLazy(initializer)
/**
* Lazy-like delegate but mutable.
*
* Inspired by [SynchronizedLazyImpl] and https://stackoverflow.com/a/47948047/6761823
*/
class MutableLazy<T>(initializer: () -> T, lock: Any? = null) : ReadWriteProperty<Any?, T>, Lazy<T> {
private object UNINITIALIZED
private var initializer: (() -> T)? = initializer
private val lock = lock ?: this
@Volatile
private var _value: Any? = UNINITIALIZED
override var value: T
get() {
val v1 = _value
if (v1 !== UNINITIALIZED) {
@Suppress("UNCHECKED_CAST")
return v1 as T
}
return synchronized(lock) {
val v2 = _value
if (v2 !== UNINITIALIZED) {
@Suppress("UNCHECKED_CAST") (v2 as T)
} else {
val typedValue = initializer!!()
_value = typedValue
initializer = null
typedValue
}
}
}
set(value) = synchronized(lock) {
_value = value
initializer = null
}
@Suppress("UNCHECKED_CAST")
override fun getValue(thisRef: Any?, property: KProperty<*>): T = value
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
this.value = value
}
override fun isInitialized(): Boolean = _value !== UNINITIALIZED
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment