The make function in Go is used exclusively for initializing objects of types: slice, map, and channel. It allocates the necessary data structure and returns a ready-to-use object (not a pointer!).
Examples:
s := make([]int, 5, 10) // slice of length 5, capacity 10 m := make(map[string]int) // empty map ch := make(chan int, 2) // buffered channel of 2
Details:
slice, parameters: length (len) and (optionally) capacity (cap).map and chan — only (optional) capacity (initial size/buffer).make function returns an already initialized object, ready for use.make is not used; they are initialized using literals or new (which returns a pointer to a zero value).Comparison with new:
new(T) returns *T, where all fields are zero.make(T) returns T only for three types: slice, map, chan.Can you get a working map through new instead of make?
m := new(map[string]int) (*m)["a"] = 1 // What will happen?
Many believe this is correct, but it will cause a panic at runtime: assignment to entry in nil map. Because the variable *m holds nil!
Correct: use make:
m := make(map[string]int) m["a"] = 1 // OK
Story
In a microservice for cache storage, a map was created via var cache map[string]interface{} without initializing make, which caused a panic in production when writing, with confusing stack traces. The problem was found only after code analysis: the map was nil.
Story
When writing a data pipeline, the buffer in the channel was forgotten and created via make(chan int). As a result, goroutines got stuck waiting for reading, although asynchronous exchange was expected. The error was noticed only during large-scale testing.
Story
In a project where initialization was done via new, some developers tried to use new([]int) instead of make([]int, 10), ultimately getting a pointer to a nil slice and runtime panic on the first write attempts.