the make Function in Go

Understanding the make Function in Go: Efficient Slice Creation and Declaration

Slices are versatile and indispensable data structures in Go, offering dynamic resizing abilities that arrays lack. However, when it comes to initializing slices, there are several options to consider, with the make function being the most versatile. Let’s dive deep into how you can utilize make for efficient slice creation and declaration. Make Function

The Power of make Function

While slice literals and the nil zero value are common methods of slice declaration, they do not allow the specification of both initial length and capacity. Here, make comes into play.

Understanding the make Function in Go: Efficient Slice Creation and Declaration

Consider the example:

x := make([]int, 5)

This syntax creates a slice of int with a length and capacity of 5. All its elements, x[0] through x[4], are automatically initialized to zero.

However, a common oversight for newcomers is to attempt the population of the initial elements with append:

x := make([]int, 5)
x = append(x, 10)

This code results in x being [0 0 0 0 0 10] since the append function extends the length of the slice. After appending the sixth element, the capacity doubles to 10.

To specify a capacity with make, the following syntax is utilized:

x := make([]int, 5, 10)

This produces a slice of int with a length of 5 and a capacity of 10. Furthermore, a slice with zero length but a specified capacity can be achieved:

x := make([]int, 0, 10)

This produces a slice with a length of 0 but a capacity of 10. Although direct indexing is not possible, values can still be appended:

x := make([]int, 0, 10)
x = append(x, 5,6,7,8)

Remember, specifying a capacity smaller than the length is a pitfall to avoid. Doing so with a constant or numeric literal results in a compile-time error, while using a variable triggers a runtime panic.

the make Function in Go

Making the Right Declaration

Given the various methods to declare slices, what should be your strategy?

Primarily, the aim should be to reduce the slice’s growth frequency. If there’s a possibility the slice might not grow (for instance, if the function could return an empty slice), a var declaration without an assigned value creates a nil slice:

var data []int

Alternatively, an empty slice literal can be employed:

var x = []int{}

This results in a non-nil, zero-length slice. Comparing such a slice to nil returns false. While nil and zero-length slices function similarly, the latter proves handy when converting slices to JSON.


In Go, the efficient creation and management of slices are crucial. By leveraging the make function and understanding the intricacies of slice declaration, developers can produce more efficient and error-free code. It’s essential to choose the right slice declaration style, keeping in mind the underlying mechanics of Go’s slice management.

For more information on related topics, check out the following articles: Best Practices for Java Architects on GitHub