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