Go New/Make

One of the aspects of Go that some people find confusing is the two predeclared functions, new and make. Both functions are specially implemented in the compiler. They take a type as an argument and return a value. This can make it seem confusing when you should use one and when you should use the other. In fact the functions are quite different.

The new function is the familiar one from C++ and other languages: it takes a type, allocates a new zero value of that type in the heap, and returns a pointer to the new value. A call new(T) returns a value *T (in Go the * in a pointer type appears before the type to which it points, not after). The important point here is that new creates a zero value of the given type.

The make function is different. It creates a non-zero value of the given type. The make function may only be used with a few specific types: slices, maps, and channels. The zero value for these types is simply nil. In the case of maps and channels, make is the only way to create a real, non-nil, value. In the case of a slice, make creates an array in the heap (as with new) and then returns a pointer to that array converted to a slice.

So you use new when you want to allocate space in the heap, e.g., for a linked list. You use make when you want to create a map or channel, or as a convenient shorthand for creating a slice.

Composite literals are also related to new, but not make. If you take the address of a composite literal, as in &(struct { i int}){1} then you get a new value on the heap. Each time you execute that code, you get a new one. So taking the address of a composite literal is similar to using new, except that you get a non-zero value. This serves as a convenient, frequently used, shorthand.

You must be logged in to post a comment.