Lazy initialization of struct members

1,687 views
Skip to first unread message

otiu...@gmail.com

unread,
Jul 21, 2013, 4:01:42 AM7/21/13
to golan...@googlegroups.com
Based on my understanding it is a common practice for structs that require some sort initialization of private members, is that they have some sort of new function. Assuming the struct needed to have some sort of method called by the user to perform, wouldn't it just be nicer to implement lazy loading in that method? Like sync.Once.

Example: 

type Ex struct {
m map[string]string
once sync.Once 
}

func (e *Ex) Run() {

e.once.Do(func() {

e.m = make(map[string]string)
})
// whatever else Run does 
}

mortdeus

unread,
Jul 21, 2013, 6:19:58 AM7/21/13
to golan...@googlegroups.com
This is confusing to me (which means its probably a bad idea to adopt as a go idiom as I definitely wont be the only one).
 How is your version different than my version? (http://play.golang.org/p/eQ786uuJWC)?

Arne Hormann

unread,
Jul 21, 2013, 6:41:05 AM7/21/13
to golan...@googlegroups.com

On Sunday, July 21, 2013 3:01:42 AM UTC-5, otiu...@gmail.com wrote:
Based on my understanding it is a common practice for structs that require some sort initialization of private members, is that they have some sort of new function. Assuming the struct needed to have some sort of method called by the user to perform, wouldn't it just be nicer to implement lazy loading in that method? Like sync.Once.

Example: 

type Ex struct {
m map[string]string
once sync.Once 
}

func (e *Ex) Run() {

e.once.Do(func() {

e.m = make(map[string]string)
})
// whatever else Run does 
}

This one won't work - a pointer receiver can legally be called on nil and will crash as e.once doesn't exists.
You can probably use that pattern for structs instead of struct pointers, but if it's more than one function, you have to copy the initialisation code everywhere - a rather bad idea.
I would avoid that pattern.

Lars Seipel

unread,
Jul 21, 2013, 10:36:20 AM7/21/13
to Arne Hormann, golan...@googlegroups.com
On Sun, Jul 21, 2013 at 03:41:05AM -0700, Arne Hormann wrote:
> This one won't work - a pointer receiver can legally be called on nil

Maybe from a language point of view but this doesn't mean it has to make
sense for every type. Think about it: of what use would methods with
pointer receivers be if they necessarily had to work with nil pointers?

otiu...@gmail.com

unread,
Jul 21, 2013, 11:11:40 AM7/21/13
to golan...@googlegroups.com
I wasn't ware that they could be called with nil, thanks for the advice, and I definitely won't do this now.

otiu...@gmail.com

unread,
Jul 21, 2013, 11:27:16 AM7/21/13
to golan...@googlegroups.com
There is functionally no difference, except mine uses thread-safe code with the sync.Once, in this case it is not needed, I just did it out of habbit.

Arne Hormann

unread,
Jul 21, 2013, 3:58:51 PM7/21/13
to golan...@googlegroups.com, Arne Hormann
You are right, but I'd still strive for a failsafe solution - esp. with a pattern created to help initialisation by avoiding a function for it and making it simpler.
My main issue isn't the nil pointer case though, it's that the initialisation code would have to be copied to every function with this receiver - which is error prone and requires too much copy-pasting for my taste.
Reply all
Reply to author
Forward
0 new messages