mardi 13 juillet 2021

How to express in Kotlin "assign value exactly once on the first call"?

Looking for a natural Kotlin way to let startTime be initialized only in a particular place and exactly once.

The following naive implementation have two problems:

  1. it is not thread safe
  2. it does not express the fact "the variable was or will be assigned exactly once in the lifetime of an Item instance"

class Item {
    var startTime: Instant?

    fun start(){
        if (startTime == null){
            startTime = Instant.now()
        }

        // do stuff
    }
}

I believe some kind of a delegate could be applicable here. In other words this code needs something similar to a lazy variable, but without initialization on first read, but only after explicit call of "touching" method. Maybe the Wrap calls could give an idea of possible implementation.

class Wrap<T>(
  supp: () -> T
){
   private var value: T? = null
   private val lock = ReentrantLock()
  
   fun get(){
     return value
   }

   fun touch(){
      lock.lock()

      try{
          if (value == null){
              value = supp()
          } else {
              throw IllegalStateExecption("Duplicate init")
          }
      } finally{
        lock.unlock()
      }
   }
}

Aucun commentaire:

Enregistrer un commentaire