The builtin new(T) function allocates “zeroed” storage for a new item of type T and returns its address, a value of type *T. In Go terminology, it returns a pointer to a newly allocated zero value of type T. For example, here are three different ways to create a pointer p that points to a zeroed bytes.Buffer value, each of which are equivalent:
// Allocate enough memory to store a bytes.Buffer value
// and return a pointer to the value's address.
var buf bytes.Buffer
p := &buf
// Use a composite literal to perform allocation and
// return a pointer to the value's address.
p := &bytes.Buffer{}
// Use the new function to perform allocation, which will
// return a pointer to the value's address.
p := new(bytes.Buffer)
The make() function, on the other hand, is a special built-in function that is used to initialize slices, maps, and channels. Note that make() can only be used to initialize slices, maps, and channels, and that, unlike the new() function, make() does not return a pointer.
Slices, maps, and channels can also be initialized using a composite literal expressions, as well as with make(). Two different (yet equivalent) ways to initialize a map m which maps string keys to bool values are given below as examples:
// Using make() to initialize a map.
m := make(map[string]bool, 0)
// Using a composite literal to initialize a map.
m := map[string]bool{}
// You can also initialize maps with initial data using a composite literal,
// as shown below:
m := map[string]bool{
"java": false,
"go": true,
}