/** * Abstract class for a LoadingMap. * Overrides [get] return type as non-nullable type V. */ abstract class LoadingMap protected constructor(private val source: MutableMap = hashMapOf()) : Map by source { final override fun get(key: K): V = source[key] ?: load(key).apply { source[key] = this } protected abstract fun load(key: K): V companion object { /** * Pseudo-constructor for inlining the load function */ inline operator fun invoke(source: MutableMap = hashMapOf(), crossinline load: (K) -> V) = object : LoadingMap(source) { override fun load(key: K): V = load(key) } } } /* * Sample LoadingMap */ val cache = LoadingMap { key: String -> key.length }