Slices, maps and strings · 3 MIN READ
make builds the header; new only allocates
Pick make or new for a slice, a map and a pointer.
The Tour's "Creating a slice with make" page and Effective Go's "Allocation with new" page are the same distinction. new(T) allocates a zero T and returns *T. That is all it does. make is only for slices, maps and channels: it allocates the backing store and returns a usable value, not a pointer to one.
new(map[string]int) is a pointer to a nil map. Writing through it panics. make(map[string]int) is a map you can write. The same trap exists for a slice: new([]int) is *[]int pointing at nil; make([]int, 0, 8) is a slice with room.
SEE THE IDEA
Allocation and initialization answer different questions
- 01
Slice
gomake([]int, 3)A usable slice with three zero elements
- 02
Map or channel
gomake(map[string]int)Initializes runtime storage
- 03
Pointer
gonew(int)Returns a pointer to a zero int
make returns a slice, map or channel; new returns a pointer.
In practice
Pick the form that matches the value your API needs. A struct literal often expresses initialization more clearly than new. A pointer to a nil map is still a pointer to a nil map: allocating the pointer does not initialize the map it points to.
Watch out
new([]int) yields a pointer to a nil slice. It does not allocate any slice elements.
Work through the exercise
package main
// ReadyMap must be writable. ZeroCounter must be a pointer to 0,
// not a nil *int.
func ReadyMap() map[string]int { return nil }
func ZeroCounter() *int { return nil }
func main() {}Trace each value and write down your reasoning. Copy the source into GopherForge or your local Go environment to compile and check it. This web page does not execute your code or send it to a compiler service.
Progress stays in this browser. No account needed.