Getting started #
In this tutorial, you learn how to use the singleton pattern in Go. We will first learn how to create a singleton, then we will see how a program with multiple goroutines can affect our singleton and how we can solve this problem using some standard Go packages.
Creating singleton #
Let's assume we are developing an application that requires an in-memory cache, we only need one instance of this cache throughout the application. Let's assume this cache needs to have a Get and a Set function, so it needs to fulfill the following interface.
package cache
// interface our cache needs to fullfill
type MyCache interface {
Get(key string) string
Set(key string, value string)
}
To fulfill, this interface let's create a struct called myCache that implements the required functions.
package cache
type MyCache interface {
Get(key string) string
Set(key string, value string)
}
// š our cache struct
type myCache struct {
}
// the actual implementation of `Get` and `Set` don't matter for this tutorial
func (c myCache) Get(key string) string {
return "default value"
}
func (c myCache) Set(key, value string) {
}
Notice carefully that the name of myCache starts with a lowercase letter, this is because we don't want anyone to create a new instance of myCache.
Now it's time to write a GetCache function that always returns the same instance of myCache.
// ...continuing from the previous example
var cache *myCache
func GetCache() MyCache {
if cache == nil {
cache = &myCache{}
}
return *cache
}
Here we are checking if the cache has not already been initialized i.e. cache is nil, then we initialize our cache and eventually return it. Once done we can use it throughout our application.
package main
import (
"fmt"
"<module_path>/cache"
)
func main() {
c := cache.GetCache()
fmt.Println(c.Get("key"))
}
Congratulations š you have now created a singleton. But hold on, your program is not safe in a concurrent environment š±.




