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 }