Quantcast
Channel: User Jonathan - Stack Overflow
Viewing all articles
Browse latest Browse all 40

Answer by Jonathan for Singleton pattern with Go generics

$
0
0

I ended up solving this using the atomic.Pointer API, and rolled it into a simple library for others to use if they're interested: singlet. Re-working the original post with singlet looks like this:

Example library code:

type Cache[T any] struct{}var singleton = &singlet.Singleton{}func getOrCreateCache[T any]() (Cache[T], err) {    return singlet.GetOrDo(singleton, func() Cache[T] {        return Cache[T]{}    })}

Client code:

stringCache := getOrCreateCache[string]()

And the Singlet library code that supports this:

var ErrTypeMismatch = errors.New("the requested type does not match the singleton type")type Singleton struct {    p   atomic.Pointer[any]    mtx sync.Mutex}func GetOrDo[T any](singleton *Singleton, fn func() T) (result T, err error) {    maybeResult := singleton.p.Load()    if maybeResult == nil {        // Lock to guard against applying fn twice        singleton.mtx.Lock()        defer singleton.mtx.Unlock()        maybeResult = singleton.p.Load()        // Double check        if maybeResult == nil {            result = fn()            var resultAny any = result            singleton.p.Store(&resultAny)            return result, nil        }    }    var ok bool    result, ok = (*maybeResult).(T)    if !ok {        return *new(T), ErrTypeMismatch    }    return result, nil}

I hope that helps anyone else who comes across this situation.


Viewing all articles
Browse latest Browse all 40

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>