type Lazy … type cacheEntry … func (e *cacheEntry[T]) get() (T, error) { … } func (z *Lazy[T]) newCacheEntry() *cacheEntry[T] { … } // Notify should be called when something has changed necessitating a new call // to Evaluate. func (z *Lazy[T]) Notify() { … } // Get should be called to get the current result of a call to Evaluate. If the // current cached value is stale (due to a call to Notify), then Evaluate will // be called synchronously. If subsequent calls to Get happen (without another // Notify), they will all wait for the same return value. // // Error returns are not cached and will cause multiple calls to evaluate! func (z *Lazy[T]) Get() (T, error) { … }