lazy
packageThis package is not in the latest version of its module.
Details
Validgo.mod file
The Go module system was introduced in Go 1.11 and is the official dependency management solution for Go.
Redistributable license
Redistributable licenses place minimal restrictions on how software can be used, modified, and redistributed.
Tagged version
Modules with tagged versions give importers more predictable builds.
Stable version
When a project reaches major version v1 it is considered stable.
- Learn more about best practices
Repository
Links
Documentation¶
Overview¶
Package lazy provides types for lazily initialized values.
Index¶
- func GFunc[T any](fill func() T) func() T
- func GFuncErr[T any](fill func() (T, error)) func() (T, error)
- type DeferredFuncs
- type DeferredInit
- type GMap
- type GValue
- type SyncValue
- func (z *SyncValue[T]) Get(fill func() T) T
- func (z *SyncValue[T]) GetErr(fill func() (T, error)) (T, error)
- func (z *SyncValue[T]) MustSet(val T)
- func (z *SyncValue[T]) Peek() (v T, ok bool)
- func (z *SyncValue[T]) PeekErr() (v T, err error, ok bool)
- func (z *SyncValue[T]) Set(val T) bool
- func (z *SyncValue[T]) SetForTest(tb testing_TB, val T, err error)
Examples¶
Constants¶
This section is empty.
Variables¶
This section is empty.
Functions¶
Types¶
typeDeferredFuncs¶added inv1.76.0
type DeferredFuncs struct {// contains filtered or unexported fields}DeferredFuncs allows one or more funcs to be deferreduntil the owner'sDeferredInit.Do method is calledfor the first time.
DeferredFuncs is safe for concurrent use. The executionorder of functions deferred by different goroutines isunspecified and must not be relied upon.However, functions deferred by the same goroutine areexecuted in the same relative order they were deferred.Warning: this is the opposite of the behavior of Go'sdefer statement, which executes deferred functions inreverse order.
func (*DeferredFuncs)Defer¶added inv1.76.0
func (d *DeferredFuncs) Defer(f func()error)bool
Defer adds a function to be called whenDeferredInit.Dois called for the first time. It returns true on success,or false ifDeferredInit.Do has already been called.
func (*DeferredFuncs)MustDefer¶added inv1.76.0
func (d *DeferredFuncs) MustDefer(f func()error)
MustDefer is likeDeferredFuncs.Defer, but panicsifDeferredInit.Do has already been called.
typeDeferredInit¶added inv1.76.0
type DeferredInit struct {DeferredFuncs}DeferredInit allows one or more funcs to be deferreduntilDeferredInit.Do is called for the first time.
DeferredInit is safe for concurrent use.
Example¶
// DeferredInit allows both registration and invocation of the// deferred funcs. It should remain internal to the code that "owns" it.var di DeferredInit// Deferred funcs will not be executed until [DeferredInit.Do] is called.deferred := di.Defer(func() error {fmt.Println("Internal init")return nil})// [DeferredInit.Defer] reports whether the function was successfully deferred.// A func can only fail to defer if [DeferredInit.Do] has already been called.if deferred {fmt.Printf("Internal init has been deferred\n\n")}// If necessary, the value returned by [DeferredInit.Funcs]// can be shared with external code to facilitate deferring// funcs without allowing it to call [DeferredInit.Do].df := di.Funcs()// If a certain init step must be completed for the program// to function correctly, and failure to defer it indicates// a coding error, use [DeferredFuncs.MustDefer] instead of// [DeferredFuncs.Defer]. It panics if Do() has already been called.df.MustDefer(func() error {fmt.Println("External init - 1")return nil})// A deferred func may return an error to indicate a failed init.// If a deferred func returns an error, execution stops// and the error is propagated to the caller.df.Defer(func() error {fmt.Println("External init - 2")return errors.New("bang!")})// The deferred function below won't be executed.df.Defer(func() error {fmt.Println("Unreachable")return nil})// When [DeferredInit]'s owner needs initialization to be completed,// it can call [DeferredInit.Do]. When called for the first time,// it invokes the deferred funcs.err := di.Do()if err != nil {fmt.Printf("Deferred init failed: %v\n", err)}// [DeferredInit.Do] is safe for concurrent use and can be called// multiple times by the same or different goroutines.// However, the deferred functions are never invoked more than once.// If the deferred init fails on the first attempt, all subsequent// [DeferredInit.Do] calls will return the same error.if err = di.Do(); err != nil {fmt.Printf("Deferred init failed: %v\n\n", err)}// Additionally, all subsequent attempts to defer a function will fail// after [DeferredInit.Do] has been called.deferred = di.Defer(func() error {fmt.Println("Unreachable")return nil})if !deferred {fmt.Println("Cannot defer a func once init has been completed")}Output:Internal init has been deferredInternal initExternal init - 1External init - 2Deferred init failed: bang!Deferred init failed: bang!Cannot defer a func once init has been completed
func (*DeferredInit)Do¶added inv1.76.0
func (d *DeferredInit) Do()error
Do calls previously deferred init functions if it is being calledfor the first time on this instance ofDeferredInit.It stops and returns an error if any init function returns an error.
It is safe for concurrent use, and the deferred init is guaranteedto have been completed, either successfully or with an error,when Do() returns.
func (*DeferredInit)Funcs¶added inv1.76.0
func (d *DeferredInit) Funcs() *DeferredFuncs
Funcs is a shorthand for &d.DeferredFuncs.The returned value can safely be passed to external code,allowing to defer init funcs without also exposingDeferredInit.Do.
typeGMap¶added inv1.86.0
type GMap[Kcomparable, Vany] struct {// contains filtered or unexported fields}
GMap is a map of lazily computedGValue pointers, keyed by a comparabletype.
Use either Get or GetErr, depending on whether your fill function returns anerror.
GMap is not safe for concurrent use.
func (*GMap[K, V])Get¶added inv1.86.0
func (s *GMap[K, V]) Get(k K, fill func() V) V
Get returns the value for k, computing it with fill if it's not alreadypresent.
func (*GMap[K, V])GetErr¶added inv1.86.0
GetErr returns the value for k, computing it with fill if it's not alreadypresent.
typeGValue¶
type GValue[Tany] struct {V T// contains filtered or unexported fields}
GValue is a lazily computed value.
Use either Get or GetErr, depending on whether your fill function returns anerror.
Recursive use of a GValue from its own fill function will panic.
GValue is not safe for concurrent use. (Mnemonic: G is for one Goroutine,which isn't strictly true if you provide your own synchronization betweengoroutines, but in practice most of our callers have been using it withina single goroutine.)
func (*GValue[T])Get¶
func (z *GValue[T]) Get(fill func() T) T
Get returns z's value, calling fill to compute it if necessary.f is called at most once.
func (*GValue[T])GetErr¶
GetErr returns z's value, calling fill to compute it if necessary.f is called at most once, and z remembers both of fill's outputs.
typeSyncValue¶
type SyncValue[Tany] struct {// contains filtered or unexported fields}
SyncValue is a lazily computed value.
Use either Get or GetErr, depending on whether your fill function returns anerror.
Recursive use of a SyncValue from its own fill function will deadlock.
SyncValue is safe for concurrent use.
Unlikesync.OnceValue, the linker can do better dead code eliminationwith SyncValue. Seehttps://github.com/golang/go/issues/62202.
func (*SyncValue[T])Get¶
func (z *SyncValue[T]) Get(fill func() T) T
Get returns z's value, calling fill to compute it if necessary.f is called at most once.
func (*SyncValue[T])GetErr¶
GetErr returns z's value, calling fill to compute it if necessary.f is called at most once, and z remembers both of fill's outputs.
func (*SyncValue[T])MustSet¶
func (z *SyncValue[T]) MustSet(val T)
MustSet sets z's value to val, or panics if z already has a value.
func (*SyncValue[T])Peek¶added inv1.70.0
Peek returns z's value and a boolean indicating whether the value has beenset successfully. If a value has not been set, the zero value of T isreturned.
This function is safe to call concurrently with Get/GetErr/Set, but it'sundefined whether a value set by a concurrent call will be visible to Peek.
To get any error that's been set, use PeekErr.
If GetErr's fill function returned a valid T and an non-nil error, Peekdiscards that valid T value. PeekErr returns both.
func (*SyncValue[T])PeekErr¶added inv1.70.0
PeekErr returns z's value and error and a boolean indicating whether thevalue or error has been set. If ok is false, T and err are the zero value.
This function is safe to call concurrently with Get/GetErr/Set, but it'sundefined whether a value set by a concurrent call will be visible to Peek.
Unlike Peek, PeekErr reports ok if either v or err has been set, not just v,and returns both the T and err returned by GetErr's fill function.
func (*SyncValue[T])Set¶
Set attempts to set z's value to val, and reports whether it succeeded.Set only succeeds if none of Get/GetErr/Set have been called before.
func (*SyncValue[T])SetForTest¶added inv1.72.0
SetForTest sets z's value and error.It's used in tests only and reverts z's state back when tb and all itssubtests complete.It is not safe for concurrent use and must not be called concurrently withany SyncValue methods, including another call to itself.
The provided tb should be a*testing.T or*testing.B.