How to name constructors

1,664 views
Skip to first unread message

Oliver

unread,
Feb 6, 2015, 4:44:54 AM2/6/15
to golan...@googlegroups.com
The recent blog article on package names also talks about how to name constructors. While the advice is straightforward, I often find myself in a situation where I need various constructors. For example:

package juice

type Juice struct{...}

func New() Juice {
}

func FromApples(a []Apple) Juice {
}

func FromOranges(o []Orange) Juice {
}


What would be the idiomatic way to name these other constructors? "FromApples"? "NewFromApples"? "CreateFromApples"?

-Oliver

David Symonds

unread,
Feb 6, 2015, 4:46:09 AM2/6/15
to Oliver, golang-nuts
How you've got it is fine. Read them how they'll appear to callers:
juice.FromApples and juice.FromOranges sound good to me.

Haddock

unread,
Feb 6, 2015, 5:01:02 AM2/6/15
to golan...@googlegroups.com
When applying OO-style message passing paradigm it would be Juice.FromApples(apples []Apple). The advantage of this approach is that you do not have to know about the constructor FromApples. You want Juice, so you look into the file defining the Juice struct and will find FromApples(apples []Apple) without having to know that this constructor exists wherever somewhere in the code. One way this could be done:

func init() {
    JuicePrototype = new(Juice)
}

type Juice struct{...}

var JuicePrototype *Juice

func main() {
    apples := // obtained somehow
    juice := JuicePrototype.FromApples(apples)
}

-- Haddock

Haddock

unread,
Feb 6, 2015, 5:04:25 AM2/6/15
to golan...@googlegroups.com
Oops. Forgot to provide FromApples:

func (self *Juice) FromApples(apples []Apple) *Juice{
    juice:= new(Juice)
// ... process apples
    return juice

Mauricio Lima

unread,
Feb 6, 2015, 7:06:31 AM2/6/15
to golan...@googlegroups.com
Why do you need a prototype juice? I prefer the original implementation, it's clearer, less code, and has less allocation.



mauriciosl

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

Haddock

unread,
Feb 6, 2015, 7:58:31 AM2/6/15
to golan...@googlegroups.com


Am Freitag, 6. Februar 2015 13:06:31 UTC+1 schrieb Mauricio Lima:
Why do you need a prototype juice? I prefer the original implementation, it's clearer, less code, and has less allocation.

Yes, I agree. I didn't notice the "package juice" statement in the first post when I wrote my reply. My fault...

Sameer Ajmani

unread,
Feb 6, 2015, 10:24:14 AM2/6/15
to Oliver, golang-nuts
What you have is fine.  I didn't mention FromX or WithY in my article; they are analogous to the time.Parse example.  New and NewT are fine defaults, but when your type has multiple constructors, use whatever reads best.  For example, in the golang.org/x/net/context package, we provide context.WithTimeout(parent context.Context, d time.Duration); the "With" prefix emphasizes that the new Context is derived from the parent one.  I've seen packages with a several FromX functions that are mapping various Xx to a common type in that package.

--

Francesc Campoy Flores

unread,
Feb 6, 2015, 6:38:34 PM2/6/15
to Haddock, golan...@googlegroups.com

Hi Haddock,

The solution you provide is definitely not idiomatic.
I agree with David, what Olivier has looks good as is.

--

Oliver

unread,
Feb 7, 2015, 12:20:33 PM2/7/15
to golan...@googlegroups.com
Thanks for all of your thoughts on this! Generally, it seems the best way is to name functions and types so they make most sense semantically from a user's point of view. And this is more important than to follow any rigid conventions (e.g. "all constructors must begin with 'New'").
Reply all
Reply to author
Forward
0 new messages