Skip to content

Instantly share code, notes, and snippets.

@bj0
Created January 26, 2017 17:15
Show Gist options
  • Save bj0/f4871f90263bc7d2a71c13f6d61710b0 to your computer and use it in GitHub Desktop.
Save bj0/f4871f90263bc7d2a71c13f6d61710b0 to your computer and use it in GitHub Desktop.
A modified version of Kotlin's lazy delegate that can be reset.
/**
* Created by Brian Parma on 2/10/16.
*
* This is basically just the lazy delegate copy and pasted, then modified so that it can be
* reset by setting it equal to null
*/
/**
* Represents a value with lazy initialization.
*
* To create an instance of [Cached] use the [cached] function.
*/
interface Cached<T> {
/**
* Gets the lazily initialized value of the current Cached instance.
* Once the value was initialized it must not change during the rest of lifetime of this Cached instance.
*/
var value: T?
/**
* Returns `true` if a value for this Cached instance has a value, and `false` otherwise.
*/
fun isCached(): Boolean
}
//@kotlin.jvm.JvmVersion
fun <T> cached(initializer: () -> T): Cached<T> = SynchronizedCachedImpl(initializer)
//@kotlin.internal.InlineOnly
inline operator fun <T> Cached<T>.getValue(thisRef: Any?, property: KProperty<*>): T? = value
inline operator fun <T> Cached<T>.setValue(thisRef: Any?, property: KProperty<*>, new_value: T?) { value = new_value }
private class SynchronizedCachedImpl<T>(initializer: () -> T, lock: Any? = null) : Cached<T>, Serializable {
private var initializer: (() -> T)? = initializer
@Volatile private var _value: Any? = null
// final field is required to enable safe publication of constructed instance
private val lock = lock ?: this
override var value: T?
set(new_value) {
synchronized(lock){
_value = new_value
}
}
get() {
val _v1 = _value
if (_v1 !== null) {
return _v1 as T
}
return synchronized(lock) {
val _v2 = _value
if (_v2 !== null) {
_v2 as T
}
else {
val typedValue = initializer!!()
_value = typedValue
// initializer = null
typedValue
}
}
}
override fun isCached(): Boolean = _value !== null
override fun toString(): String = if (isCached()) value.toString() else "Cached value is not set yet."
// private fun writeReplace(): Any = InitializedLazyImpl(value)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment