make a lazy var in scala

后端 未结 5 1922
我在风中等你
我在风中等你 2021-01-11 15:04

Scala does not permit to create laze vars, only lazy vals. It make sense.

But I\'ve bumped on use case, where I\'d like to have similar capability. I need a lazy var

5条回答
  •  灰色年华
    2021-01-11 15:41

    I've summarized all provided advices for building custom container:

    object LazyVar {
    
      class NotInitialized extends Exception
    
      case class Update[+T]( update : () => T )
      implicit def impliciţUpdate[T](update: () => T) : Update[T] = Update(update)
    
      final class LazyVar[T] (initial : Option[Update[T]] = None ){
        private[this] var cache : Option[T] = None
        private[this] var data : Option[Update[T]] = initial
    
        def put(update : Update[T]) : LazyVar[T] = this.synchronized {
          data = Some(update)
          this
        }
        def set(value : T) : LazyVar[T] = this.synchronized {
          data = None
          cache = Some(value)
          this
        }
        def get : T = this.synchronized { data match {
          case None => cache.getOrElse(throw new NotInitialized)
          case Some(Update(update)) => {
            val res = update()
            cache = Some(res)
            res
          }
        } }
    
        def := (update : Update[T]) : LazyVar[T] = put(update)
        def := (value : T) : LazyVar[T] = set(value)
        def apply() : T = get
      }
      object LazyVar {
        def apply[T]( initial : Option[Update[T]] = None ) = new LazyVar[T](initial)
        def apply[T]( value : T) = {
          val res = new LazyVar[T]()
          res.set(value)
          res
        }
      }
      implicit def geţLazy[T](lazyvar : LazyVar[T]) : T = lazyvar.get
    
      object Test {
        val getInt1 : () => Int = () => {
          print("GetInt1")
          1
        }
        val getInt2 : () => Int = () => {
          print("GetInt2")
          2
        }
        val li : LazyVar[Int] = LazyVar()
        li := getInt1
        li := getInt2
        val si : Int = li
      }
    }
    

提交回复
热议问题