Kinda lazy, kinda lateinit, resettable property

I’ve got an object that has some expensive-to-compute values which rely on each other. So I considered making them by lazy. And I can make sure that only one thread is calculating it with the default LazyThreadSafetyMode.SYNCHRONIZED

But in the chain of myClass.c depends on myClass.b depends on myClass.a, I don’t think I can say “b changed, which invalidated c”. I think I need a way to say “clear out the lazy value and recompute next time it is requested”

I hacked something together. It isn’t pretty, or synchronized, and all users of this solution need to !! to avoid nulls that will never happen. Is there a better way to do this? A custom byLazyButResettable perhaps?

private var b: MyThing? = null
  get() = field ?: a!!.doStuff().also { field = it }
  set(value) {
    c = null
    field = value

Not that I am aware of. But you should be able to build one yourself quite easily. Just take a look at the sources for lazy. If I remember correctly the use something like

object EmptyValue
private var _value: Any? = EmptyValue
val value: T get() = if(_value == EmptyValue) { _value = _value as T} else _value as T

plus some syncronization. The EmptyValue object is used instead of null to allow for nullable types.

1 Like