make(T, ...) — creates and initializes slices, maps, and channels, returning a ready-to-use value. new(T) — allocates zeroed memory for any type and returns a *T pointer.
For slices, make([]int, 0, 500) creates a slice with preallocated backing storage. For maps, it creates the hash table. For channels, it allocates the ring buffer. The result is always immediately usable.
1s := make([]int, 0, 500) // preallocated for 500 items2m := make(map[string]int) // ready to write to3ch := make(chan int, 10) // buffered channel
new allocates sizeof(T) bytes, zeroes them, and returns *T. For simple types this works fine. For slices/maps/channels, the zero value is nil — you must still call make to make them functional.
1p := new(int) // *int → 0, usable2s := new([]int) // *[]int → nil, NOT usable3// Must do: *s = make([]int, 0)
When to use:
&T{...} literal syntax for struct initialization.Common mistakes:
new([]int) and trying to append — nil slice panic.make([]int, 10) (len=10, full of zeros) with make([]int, 0, 10) (len=0, cap=10).make([]int, 0, expectedSize) avoids repeated reallocation.make on a non-slice/map/channel type — compilation error.