github.com/mitranim/gg@v0.1.17/lazy.go (about)

     1  package gg
     2  
     3  import "sync"
     4  
     5  /*
     6  Creates `Lazy` with the given function. See the type's description for details.
     7  */
     8  func NewLazy[A any](fun func() A) *Lazy[A] { return &Lazy[A]{fun: fun} }
     9  
    10  /*
    11  Similar to `sync.Once`, but specialized for creating and caching one value,
    12  instead of relying on nullary functions and side effects. Created via `NewLazy`.
    13  Calling `.Get` on the resulting object will idempotently call the given function
    14  and cache the result, and discard the function. Uses `sync.Once` internally for
    15  synchronization.
    16  */
    17  type Lazy[A any] struct {
    18  	val  A
    19  	fun  func() A
    20  	once sync.Once
    21  }
    22  
    23  /*
    24  Returns the inner value after idempotently creating it.
    25  This method is synchronized and safe for concurrent use.
    26  */
    27  func (self *Lazy[A]) Get() A {
    28  	self.once.Do(self.init)
    29  	return self.val
    30  }
    31  
    32  func (self *Lazy[_]) init() {
    33  	fun := self.fun
    34  	self.fun = nil
    35  	if fun != nil {
    36  		self.val = fun()
    37  	}
    38  }