Cả hai đều cấp phát, nhưng cho mục đích khác nhau:
new(T)— dùng cho mọi kiểu. Cấp phát một T đã zeroed và trả về con trỏ*T. Nó không khởi tạo gì thêm.make(T, ...)— chỉ cho slice, map, channel. Khởi tạo cấu trúc bên trong (backing array, hash table, buffer) và trả về giá trị T đã sẵn sàng dùng, không phải con trỏ.
Hình dung: new([]int) cho *[]int trỏ tới một slice nil — gần như vô dụng. Muốn slice thật thì dùng make.
go
p := new(int) // *int, *p == 0
m := make(map[string]int) // map dùng được ngay
s := make([]int, 0, 8) // len 0, cap 8