Skip to content

Instantly share code, notes, and snippets.

@elizarov
Last active October 10, 2017 10:57
Show Gist options
  • Save elizarov/8420174dff16ecacb664c83525f135d4 to your computer and use it in GitHub Desktop.
Save elizarov/8420174dff16ecacb664c83525f135d4 to your computer and use it in GitHub Desktop.
Kotlin approach to syntactically local static caching
import java.util.concurrent.atomic.AtomicReference
private val cache = object : ClassValue<AtomicReference<Any?>>() {
override fun computeValue(type: Class<*>) = AtomicReference<Any?>()
}
/**
* Caches the given expression statically.
*
* Use it like this:
* ```
* static { expr() }.thing()
* ```
*
* See https://twitter.com/lukaseder/status/917677218679214080
*/
@Suppress("UNCHECKED_CAST")
public fun <T : Any> static(expr: () -> T): T {
val clazz = expr::class.java
val ref = cache[clazz]
ref.get()?.let { return it as T }
// using double-checked locking to ensure at most one invocation of expr
synchronized(clazz) {
ref.get()?.let { return it as T }
val value = expr()
ref.set(value)
return value
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment