diff --git a/Misc/Initialization.go b/Misc/Initialization.go new file mode 100644 index 0000000..53f2dba --- /dev/null +++ b/Misc/Initialization.go @@ -0,0 +1,28 @@ +package Misc + +import "sync" + +type Singleton[T any] struct { + once sync.Once + Val Nullable[T] + Init func() Result[T] +} + +func NewSingleton[T any](f func() Result[T]) *Singleton[T] { + return &Singleton[T]{ + Init: f, + Val: NewNullable[T](), + } +} + +func (this *Singleton[T]) Get() Result[T] { + var err error + this.once.Do(func() { + if this.Val.IsNil { + newObj := this.Init() + this.Val.Value = newObj.Value + err = newObj.Err + } + }) + return Result[T]{Value: this.Val.Value, Err: err} +} diff --git a/Tests/Misc/Initialization_test.go b/Tests/Misc/Initialization_test.go new file mode 100644 index 0000000..82099be --- /dev/null +++ b/Tests/Misc/Initialization_test.go @@ -0,0 +1,19 @@ +package Misc + +import ( + "github.com/RENCI/GoUtils/Misc" + "github.com/stretchr/testify/assert" + "testing" +) + +func Test_Singleton(t *testing.T) { + + r := 1 + s := Misc.NewSingleton(func() Misc.Result[int] { + r += 1 + return Misc.NewResult(r, nil) + }) + res := s.Get() + res = s.Get() + assert.Equal(t, 2, res.Value) +}