Singleton pattern in Go

1,653 views
Skip to first unread message

Yan Dai

unread,
Dec 16, 2014, 5:23:38 PM12/16/14
to golan...@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
    }

Henrik Johansson

unread,
Dec 16, 2014, 5:33:27 PM12/16/14
to Yan Dai, golang-nuts

I think at the very least you need a lock or some other way to avoid a race on the creation of the singleton.

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

Skip Tavakkolian

unread,
Dec 16, 2014, 5:46:20 PM12/16/14
to Yan Dai, golan...@googlegroups.com
maybe sync.Once?



--

Andy Balholm

unread,
Dec 16, 2014, 5:46:55 PM12/16/14
to Yan Dai, golan...@googlegroups.com
If I needed to translate a singleton into Go, I would use an empty struct (type singleton struct{}). So the object would not store any state or take up any memory. All “instances” would be interchangeable. Then the state would be in global variables, with initialization protected by a sync.Once.

Yan Dai

unread,
Dec 16, 2014, 5:52:27 PM12/16/14
to Andy Balholm, golan...@googlegroups.com
So, Do your guys think singleton pattern can be a good design pattern for Go?

On Wed, Dec 17, 2014 at 11:46 AM, Andy Balholm <andyb...@gmail.com> wrote:
If I needed to translate a singleton into Go, I would use an empty struct (type singleton struct{}). So the object would not store any state or take up any memory. All “instances” would be interchangeable. Then the state would be in global variables, with initialization protected by a sync.Once.


--
Yours sincerely,
Yan Dai

Dave Cheney

unread,
Dec 16, 2014, 5:56:41 PM12/16/14
to golan...@googlegroups.com
Initially I'd say no.

Can you explain more about the problem you're trying to solve, not way you have chosen to solve it.

Andy Balholm

unread,
Dec 16, 2014, 5:58:35 PM12/16/14
to Yan Dai, golan...@googlegroups.com
It depends on what you’re trying to do.

The singleton pattern is less useful in Go than in languages like Java where everything is an object. Often you should use package variables and regular functions instead of a singleton object. But sometimes you need to create an object so that you can fulfill an interface. Then it’s useful to create an empty struct that acts like a singleton.

Henrik Johansson

unread,
Dec 16, 2014, 5:59:08 PM12/16/14
to Yan Dai, Andy Balholm, golang-nuts

What do you want it for? Might sound strange but if you control all code you can just not create more than one. Alternatively panic if it can not work with more than one instances.

--

Yan Dai

unread,
Dec 16, 2014, 6:04:48 PM12/16/14
to Andy Balholm, golan...@googlegroups.com
Hi Guys,

Simply, the problem I am trying to do is to compare Java and Go at language level since I am new to Go and more familiar to Java.
This singleton pattern is not for solving any real problems.

Regards,
Yan 

On Wed, Dec 17, 2014 at 11:58 AM, Andy Balholm <andyb...@gmail.com> wrote:
It depends on what you’re trying to do.

The singleton pattern is less useful in Go than in languages like Java where everything is an object. Often you should use package variables and regular functions instead of a singleton object. But sometimes you need to create an object so that you can fulfill an interface. Then it’s useful to create an empty struct that acts like a singleton.


Dan Kortschak

unread,
Dec 16, 2014, 6:08:52 PM12/16/14
to Yan Dai, Andy Balholm, golan...@googlegroups.com
Some things are not translatable into another idiom in a meaningful way.

Yan Dai

unread,
Dec 16, 2014, 6:09:37 PM12/16/14
to golan...@googlegroups.com
Hi everyone,


As I am very new to Go.
Now I have realise that I had made some mistake.
The problem is that I am trying to learn Go in Java way.
However, Go is not absolutely a similar OO language as Java. 
Therefore, singleton pattern can be less useful as it is in Java.
Sync.Once can be a good lock as what "synchronized" does in Java, but I understand that this is a wrong way to solve problem by using Go.

Thanks to everyone again,
Learnt alot

Andy Balholm

unread,
Dec 16, 2014, 6:09:37 PM12/16/14
to Yan Dai, golan...@googlegroups.com
Since Go is not a traditional class-based object-oriented language, most of the classic OO “design patterns” are awkward to translate into Go. Go has its own design patterns (although I don’t think anyone has written up a taxonomy of them).

Once you’ve learned Go’s basic syntax, a better way to get a feel for how it compares to Java is to take some real problems (even toy ones, but programs that actually do something) and write programs that solve them in both languages.

Ian Lance Taylor

unread,
Dec 16, 2014, 6:27:38 PM12/16/14
to Yan Dai, golang-nuts
On Tue, Dec 16, 2014 at 2:23 PM, Yan Dai <alvin...@gmail.com> wrote:
>
> I am trying to implement a singleton pattern by using Go since I am a Gopher
> from Java world.

The "singleton pattern" in Java is known as a global variable in most
other languages, including Go.

Just use a global variable.

If synchronization is required write small functions that lock a mutex
before reading or writing the variable.

Ian

Rob Pike

unread,
Dec 16, 2014, 7:15:31 PM12/16/14
to Ian Lance Taylor, Yan Dai, golang-nuts
Use a global variable, and if possible initialize it in an init function or as an expression at top level in the file, as in

var singleton = someExpression()

Then you won't have to worry about synchronization at all.

-rob



Ian

Russel Winder

unread,
Dec 17, 2014, 4:02:53 AM12/17/14
to golan...@googlegroups.com

On Tue, 2014-12-16 at 14:23 -0800, Yan Dai wrote:
> Hi guys,
>
> I am trying to implement a singleton pattern by using Go since I am a
> Gopher from Java world.

Why would you want a singleton? I appreciate the Java world is full of
them, and Scala is making things a little bit worse by reifying in the
language (though this is ameliorated by Scala's excellent obsession
with immutable), but the C++ world is trying to remove them as
anathema. Idioms such as Parameterize from Above are far superior,
since they admit testing of the code: singletons more or less ruin any
ability to properly test code.

So rather than try and recreate the problems of the Java world when
switching to Go, maybe rethink the design of your application to
better fit the computational model of Go. There is almost no code that
doesn't benefit from being recast in a more dataflow way, and Go is
ideal for this using channels and goroutines.

> 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?

As many people will tell you, as an application programmer if you use
the synchronized keyword in Java code, you are doing it wrong. Threads
are infrastructure and should only ever be used in foundation
frameworks such as fork/join. Any and all concurrency and parallelism
in Java should be handled with things from java.util.concurrent and
Futures.

> 2. is singleton pattern a good practice for Go compared to Java?

I would hope not. Especially as it is not good practice in Java!

> 3. Ifound 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
> }

Given the my earlier comments, I think you'll will appreciate I have
to say "No.".

--
Russel.
=============================================================================
Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel...@ekiga.net
41 Buckmaster Road m: +44 7770 465 077 xmpp: rus...@winder.org.uk
London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder

Russel Winder

unread,
Dec 17, 2014, 4:14:24 AM12/17/14
to golan...@googlegroups.com

On Wed, 2014-12-17 at 12:02 +1300, Yan Dai wrote:
> Hi Guys,
>
> Simply, the problem I am trying to do is to compare Java and Go at
> language
> level since I am new to Go and more familiar to Java.
> This singleton pattern is not for solving any real problems.

It is always a good thing to compare languages, especially when they
have different idioms and models: there is strong experimental
evidence (*) that expertise in programming is directly related to the
number of different computational models you can work with reasonably
well.

The difficulty in doing the comparison is to ensure you use the
correct language idioms. Transliteration of code from one language to
another rarely provides good implementation in the target languages,
and doesn't give as much comparative evidence as you might think.

So you need to go back one stage to the problem to which a solution is
being provided. Write an idiomatic Java version (which probably
shouldn't involve Singleton!). Then step back from that and write (or
get someone knowledgeable about Go to write) an idiomatic Go version
of the same problem. Then compare things.

The point here is that it is not the code structures that are
important it is the idioms of solving a problem that are.


(*) See the psychology of programming literature from about 1987 to
date.

Russel Winder

unread,
Dec 17, 2014, 4:19:37 AM12/17/14
to golan...@googlegroups.com

On Tue, 2014-12-16 at 15:09 -0800, Andy Balholm wrote:
> Since Go is not a traditional class-based object-oriented language,
> most of the classic OO “design patterns” are awkward to translate
> into Go. Go has its own design patterns (although I don’t think
> anyone has written up a taxonomy of them).

Technically a programming language cannot have design patterns. It can
have implementation idioms, but design patters are (supposedly)
language independent. The fact that GoF is all about Smalltalk and C++
of the 1992–1994 period means that some of the patterns were OO
specific, do not apply to non-OO languages, and with the changes to
programming languages in the intervening 20 years, many of the patters
are outdated and for today's programming, simply wrong. cf. Singleton,
Command, Strategy, etc.

> Once you’ve learned Go’s basic syntax, a better way to get a feel
> for how it compares to Java is to take some real problems (even toy
> ones, but programs that actually do something) and write programs
> that solve them in both languages.

Definitely.

It is surprising how much can be learnt from really quite trivial
problems. I have one I have been working on for 7 years and as I add
new languages and as the languages evolve, so I keep changing the code
and learning new stuff.

egon

unread,
Dec 17, 2014, 5:19:43 AM12/17/14
to golan...@googlegroups.com


On Wednesday, 17 December 2014 00:23:38 UTC+2, Yan Dai wrote:
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?

It's as good practice as in Java... i.e. not really, except some cases.

Singleton provides two features:

1. Global Access
2. Ensuring single instance of a thing

1. is sometimes needed and simplifies some code, although testing can become harder
2. this is needed when you are talking to a third party thing that you cannot have multiple instances of - i.e. some DLL, some service that allows only a single connection and any additional connections would terminate

If you only need 1. use a global variable
If you only need 2. use a package that hides multiplexing to a single connection.

If you need both, then you may need a singleton.

Konstantin Khomoutov

unread,
Dec 17, 2014, 11:49:07 AM12/17/14
to Yan Dai, golan...@googlegroups.com, Russel Winder
On Wed, 17 Dec 2014 09:13:38 +0000
Russel Winder <rus...@winder.org.uk> wrote:

> It is always a good thing to compare languages, especially when they
> have different idioms and models: there is strong experimental
> evidence (*) that expertise in programming is directly related to the
> number of different computational models you can work with reasonably
> well.

I'm with Russel on this.

I would advise you, Yan Dai, to dabble with Erlang first, before
touching Go. The reason is simple: Go in my opinion is in almost every
way superior to Java but it's still a procedural language, so when
you're learning Go, you're having hard time "unlearning" Java -- because
the Go code looks suspiciously similar to that in Java.
Learning Erlang should shatter your Java mindset because these two
languages have no similarity at all -- both in approaches to solving
problems and in how the code looks.
And I'm not advising to learn some another ("more cool") functional
language, like Haskell, because there you might easily get drowned in
foreign concepts (unless you have at least a PhD in math). Erlang is
very easy to grok, so you'll be up to speed with its basics in a couple
of hours.

Start with [1] and continue with [2].

My advice might seem whimsical and strange, given the topic of this
list, but I think that the OP will benefit from a somewhat radical
paradigm shift to free himself from the chores of the single
programming language and the world view it instills in the programmer's
mind.

1. http://learnyousomeerlang.com/
2. https://pragprog.com/book/jaerlang2/programming-erlang
Reply all
Reply to author
Forward
0 new messages