Understanding the Difference Between make and new in Go
In the Go programming language, memory allocation and initialization are crucial concepts that allow developers to manage data structures efficiently. Two built-in functions that play a significant role in this context are make and new. Although they might seem similar at first glance, they serve different purposes and are used in different scenarios. In this blog post, we'll delve into the nuances of these functions, their differences, and when to use each one.
The new Function
The new function is a built-in function in Go that allocates memory for a variable of a specified type. The function returns a pointer to the newly allocated memory. This means that new(T) allocates zeroed storage for a new item of type T and returns its address, a value of type *T. The memory allocated by new is initialized to zero values for the type, which means numbers are set to 0, booleans to false, strings to "", and pointers to nil.
Here's a simple example of using new to allocate memory for an integer:
ptr := new(int)
*ptr = 100
fmt.Println(*ptr) // Output: 100
In this example, new(int) allocates memory for an integer, initializes it to 0, and returns a pointer to it. The pointer is then used to set the value of the memory location to 100.
The make Function
The make function, on the other hand, is used to allocate and initialize non-zeroed memory for built-in data structures like slices, maps, and channels. Unlike new, which only allocates memory, make also initializes the memory with a non-zero value that is dependent on the type. For instance, make can be used to create a slice with a specified length and capacity, a map, or a channel with a specified buffer size.
Here's how you can use make to create a slice:
s := make([]int, 10, 100)
fmt.Println(len(s), cap(s)) // Output: 10 100
In this example, make creates a slice of integers with a length of 10 and a capacity of 100. The slice is initialized with zero values for its elements.
Key Differences
The key differences between make and new can be summarized as follows:
Purpose:
newallocates memory and returns a pointer to it, initializing the memory to zero values of the specified type.make, however, is used to initialize slices, maps, and channels, not just allocate memory.Return Type:
new(T)returns a pointer to the newly allocated memory (*T), whilemake(T, args)returns an initialized value of typeT.Usage:
newis generally used when you need a pointer to a value of a certain type.makeis used when you need to initialize slices, maps, or channels, which require not just memory allocation but also initialization to their zero values.
When to Use Each
Use
newwhen you need a pointer to a new variable. It's particularly useful when working with structs in Go, allowing you to directly manipulate the fields of the struct through the pointer.Use
makewhen working with slices, maps, or channels, as these types require initialization beyond simple memory allocation.
Conclusion
Understanding the difference between make and new is fundamental for effective memory management in Go. While new is for allocating memory for a single instance of a type, make is tailored for initializing the built-in types that represent collections or communication mechanisms. By knowing when to use each, you can write more idiomatic and efficient Go code.