singleton pattern in Go

35 views
Skip to first unread message

Yan Dai

unread,
Dec 16, 2014, 5:24:01 PM12/16/14
to gola...@googlegroups.com
Hi guys,

I am trying to implement a singleton pattern by using Go since I am a Gopher from Java world. 
There are few questions I currently have.
1. in Java, we use synchronized keywords to forbidden multiple threads creating multiple instance then how to do it in Go?
2. is singleton pattern a good practice for Go compared to Java?
3. I found the following code from stackoverflow, so is this a good solution?
 
package singleton
    
    type singleton struct {
        O interface{}
    }
    
    var instantiated *single = nil // private instance of singleton
    
    func New() *single {
        if instantiated == nil {
            instantiated = new(single)
        }
        return instantiated
    }

Dave Cheney

unread,
Dec 16, 2014, 5:29:13 PM12/16/14
to gola...@googlegroups.com

You can use an init() function to achieve most of this. For the rest, sync.Once will suite.

I wouldn't use that stack overflow pattern, its far to complicated, not type safe, and has a data race.

--
--
* You received this message because you are subscribed to the Google Groups "golang-nz" group.
* To post to this group, send email to gola...@googlegroups.com
* To subscribe from this group, send email to golang-nz...@googlegroups.com
* To unsubscribe from this group, send email to golang-nz+...@googlegroups.com
* For more options, visit this group at http://groups.google.com/group/golang-nz?hl=en-GB?hl=en-GB

---
You received this message because you are subscribed to the Google Groups "golang-nz" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nz+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Yan Dai

unread,
Dec 16, 2014, 5:43:05 PM12/16/14
to gola...@googlegroups.com

something like this?

<pre>
package singleton

import "sync"

type singleton struct {}

var instance *singleton
var once sync.Once

func New() *single {
if instantiated == nil {
once.Do(func() {
instantiated = new(single)
})
}
return instantiated
}
</pre>

You received this message because you are subscribed to a topic in the Google Groups "golang-nz" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nz/98S8i41Ga7I/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nz+...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.


--
Yours sincerely,
Yan Dai

Dave Cheney

unread,
Dec 16, 2014, 5:51:38 PM12/16/14
to gola...@googlegroups.com

There is a still a data race, on the value before the sync.Do.

Check the std lib for examples, sorry I can't be more forthcoming (phone)

Also, do you really need a singleton? Why not

var thing = Thing{...}

It would be rare to import a package with an expensive value constructed at init time and to not then use that value so lazy initialisation may be unnecessary.

Am Laher

unread,
Dec 17, 2014, 4:01:36 AM12/17/14
to gola...@googlegroups.com
I agree with Dave here.

In answer to your question 2 (is singleton pattern a good practice for Go compared to Java?), I'd say that it's questionable for both languages, and its usefulness is limited to only certain scenarios. In my experience, software often grows in such a way that this unique instance grows from being unique per-process, into a single instance within a given context of the process. 

I'd recommend something more like this:

So, for your 'singleton' I'd suggest using a private variable, of a private type. This variable could only be returned from a public factory function 'GetInstance()'.
I've made the private variable implement an interface so that GetInstance() can be used publicly.



Reply all
Reply to author
Forward
0 new messages