Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
165 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package lazy | ||
|
||
import ( | ||
"sync" | ||
) | ||
|
||
// Value is a simple wrapper around sync.Once that can lazy load a value | ||
// Once Zero is called, this value always returns the zero value for T. | ||
type Value[T any] struct { | ||
once *sync.Once | ||
|
||
value T | ||
|
||
onZero func() | ||
} | ||
|
||
// New creates a new Value. The provided onZero function will be called when Zero is called | ||
func New[T any](onZero func()) *Value[T] { | ||
return &Value[T]{ | ||
once: &sync.Once{}, | ||
onZero: onZero, | ||
} | ||
} | ||
|
||
// Fetch returns the lazy value, calling populate to fetch it the first time | ||
func (c *Value[T]) Fetch(populate func() T) T { | ||
c.once.Do(func() { | ||
c.value = populate() | ||
}) | ||
|
||
return c.value | ||
} | ||
|
||
// Zero causes any future calls to Fetch to return the zero value for this function | ||
func (c *Value[T]) Zero() { | ||
var v T | ||
c.value = v | ||
c.onZero() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package lazy | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestValue(t *testing.T) { | ||
var reset bool | ||
sut := New[string](func() { | ||
reset = true | ||
}) | ||
|
||
assert.False(t, reset, "cache was reset unexpectedly") | ||
|
||
assert.Equal(t, "a", sut.Fetch(func() string { | ||
return "a" | ||
})) | ||
|
||
assert.False(t, reset, "cache was reset unexpectedly") | ||
|
||
assert.Equal(t, "a", sut.Fetch(func() string { | ||
return "b" | ||
})) | ||
|
||
assert.False(t, reset, "cache was reset unexpectedly") | ||
|
||
sut.Zero() | ||
assert.True(t, reset, "expected the cache to be reset") | ||
|
||
assert.Zero(t, sut.Fetch(func() string { | ||
return "c" | ||
})) | ||
} |