ProgrammingGo Developer

Explain the features of the built-in function make in Go: when it is necessary, how it works with initialization slicing for maps, slices, and channels? What errors occur due to incorrect usage of make and new?

Pass interviews with Hintsage AI assistant

Answer

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:

  • For slice, parameters: length (len) and (optionally) capacity (cap).
  • For map and chan — only (optional) capacity (initial size/buffer).
  • The make function returns an already initialized object, ready for use.
  • For other types (struct, array) 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.

Trick Question

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

Examples of real errors due to lack of understanding of the nuances


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.