What should I name a constructor if it does not return a pointer?

1,003 views
Skip to first unread message

Hǎiliàng

unread,
Nov 25, 2013, 9:22:28 PM11/25/13
to golan...@googlegroups.com
When a constructor (function) returns a pointer of a struct (or other nullable type like an interface), it is usually named like NewXXX, and there is also a builtin function new that returns a pointer, so their names are consistent. The word "new" usually implies that an allocation happens and it needs a pointer (or interface) to point to the allocated space, and the pointer (interface) itself could be nil.

But what if the constructor does not return a pointer but a struct itself? Should I also name it as NewXXX? or MakeXXX? or anything else?

Hǎiliàng

Dave Cheney

unread,
Nov 25, 2013, 9:25:33 PM11/25/13
to Hǎiliàng, golang-nuts
On Tue, Nov 26, 2013 at 1:22 PM, Hǎiliàng <hwan...@gmail.com> wrote:
> When a constructor (function) returns a pointer of a struct (or other
> nullable type like an interface), it is usually named like NewXXX, and there
> is also a builtin function new that returns a pointer, so their names are
> consistent. The word "new" usually implies that an allocation happens and it
> needs a pointer (or interface) to point to the allocated space, and the
> pointer (interface) itself could be nil.

If you free yourself from the notion that New implies allocation, and
embrace the idea that New returns a new thing for you to use, that
would solve the problem, right ?

>
> But what if the constructor does not return a pointer but a struct itself?
> Should I also name it as NewXXX? or MakeXXX? or anything else?
>
> Hǎiliàng
>
> --
> 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/groups/opt_out.

Hailiang Wang

unread,
Nov 25, 2013, 9:39:26 PM11/25/13
to Dave Cheney, golang-nuts
The key point is: Go has two builtin functions: new and make. Function
new is pure allocation but make does initialization after allocation.
If all the constructors in the Go standard library are named MakeXXX,
then there is no confusion: "new" stands for pure allocation and the
constructor should always be named as MakeXXX for the extra
initialization. However, all the constructors in the standard library
are named as NewXXX, that's where the confusion comes.

But anyway, probably I should always name a constructor as NewXXX and
stops thinking about the inconsistency with "new", "make" builtin
functions.

Hǎiliàng

Jesse McNelis

unread,
Nov 25, 2013, 9:46:03 PM11/25/13
to Hailiang Wang, Dave Cheney, golang-nuts
On Tue, Nov 26, 2013 at 1:39 PM, Hailiang Wang <hwan...@gmail.com> wrote:
The key point is: Go has two builtin functions: new and make. Function
new is pure allocation but make does initialization after allocation.
If all the constructors in the Go standard library are named MakeXXX,
then there is no confusion: "new" stands for pure allocation and the
constructor should always be named as MakeXXX for the extra
initialization. However, all the constructors in the standard library
are named as NewXXX, that's where the confusion comes.

Many constructors aren't named NewXXX() because it's common for the purpose of the construction to be important and the construction itself to be rather irrelevant.
Examples include:
time.Date()
time.Parse()
time.Unix()
net.Dial()
http.FileServer()
exec.Command()
reflect.TypeOf()
reflect.ValueOf()

This is one of the reasons not to have constructors in the language because generally the fact that's you're creating a data structure isn't as important as why.

Kevin Gillette

unread,
Nov 26, 2013, 12:36:11 PM11/26/13
to golan...@googlegroups.com, Hailiang Wang, Dave Cheney, jes...@jessta.id.au
On Monday, November 25, 2013 7:46:03 PM UTC-7, Jesse McNelis wrote:
Many constructors aren't named NewXXX() because it's common for the purpose of the construction to be important and the construction itself to be rather irrelevant.
Examples include:
time.Date()
time.Parse()
time.Unix()

Good example! The "New" forms of these might have respectively been NewFromTimeParts, NewFromString, NewFromUnixTimeStamp. The problem with adding more to a name is that doing so often demands even a further sacrifice of conciseness (if it's long, it might as well be even longer). New doesn't really add anything here, since the time package makes it pretty clear that all functions produce either a Time, a Duration, or a Location.
 
net.Dial()
http.FileServer()
exec.Command()
reflect.TypeOf()
reflect.ValueOf()

os.Open
os.Create
os.OpenFile

In line with Jesse's reasoning, I find that New is often useful when the 'why' is obvious but the 'how' is not (when the zero value(s) of the type or some of its unexported fields aren't usable). Many single-type-centric packages have a function named exactly "New" for that purpose.
Reply all
Reply to author
Forward
0 new messages