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: new allocates 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), while make(T, args) returns an initialized value of type T.

  • Usage: new is generally used when you need a pointer to a value of a certain type. make is 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 new when 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 make when 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.

Previous
Previous

How to Effectively Unit Test Goroutines in Go: Tips & Tricks

Next
Next

Understanding Type Aliases in Go: A Comprehensive Guide