make(T, ...) — initializes slices, maps, and channels with usable internal structures. new(T) — allocates zeroed memory and returns *T.
For slices, make([]int, 0, 500) preallocates backing storage for 500 elements. For maps and channels, make sets up hash tables and ring buffers. The result is always immediately usable.
1s := make([]int, 0, 500) // preallocated2m := make(map[string]int) // ready to write3ch := make(chan int, 10) // buffered channel
new allocates sizeof(T) bytes, zeroes them, returns *T. For simple types this works fine. For slices/maps/channels, the zero value is nil — unusable until make is called.
1p := new(int) // *int → 0, usable2s := new([]int) // *[]int → nil, NOT usable3// Must do: *s = make([]int, 0)
When to use:
&T{...} for structs.Common mistakes:
new([]int) returns nil slice — must make to use.make([]int, 10) has len=10 (zeros), not empty with cap=10.make on non-slice/map/channel — compile error.