new
vs. make
: Understanding the Differences and When to Use EachIn Go, both new
and make
are used for memory allocation, but they serve different purposes and are used in different contexts. Here's a detailed look at the differences between new
and make
, and guidelines on when to use each.
new
new
is used to allocate memory for a value of a specific type and returns a pointer to it.new
is zeroed out, meaning all fields are set to their zero values.Syntax:
goptr := new(Type)
Example:
gopackage main
import "fmt"
func main() {
p := new(int) // Allocates memory for an int and returns a pointer to it
fmt.Println(*p) // Output: 0 (zero value of int)
*p = 42
fmt.Println(*p) // Output: 42
}
In this example, new(int)
allocates memory for an integer, initializes it to 0, and returns a pointer to that integer.
make
make
is used to allocate and initialize slices, maps, and channels.make
not only allocates memory but also initializes the internal data structures of slices, maps, and channels.Syntax:
goslice := make([]Type, length, capacity)
mapVar := make(map[KeyType]ValueType, capacity)
ch := make(chan Type, bufferSize)
Examples:
gopackage main
import "fmt"
func main() {
// Creating a slice with make
slice := make([]int, 5) // Allocates and initializes a slice of int with length 5
for i := range slice {
slice[i] = i * i
}
fmt.Println(slice) // Output: [0 1 4 9 16]
// Creating a map with make
m := make(map[string]int)
m["foo"] = 1
m["bar"] = 2
fmt.Println(m) // Output: map[foo:1 bar:2]
// Creating a channel with make
ch := make(chan int, 2)
ch <- 1
ch <- 2
fmt.Println(<-ch) // Output: 1
fmt.Println(<-ch) // Output: 2
}
In these examples, make
initializes slices, maps, and channels with their internal data structures, making them ready for use.
Types:
new
can be used with any type, but it returns a pointer to the allocated memory.make
is only used with slices, maps, and channels and returns an initialized (but not necessarily filled) value of the type (not a pointer).Initialization:
new
zeroes out the memory but does not initialize complex data structures.make
initializes the data structures required for slices, maps, and channels.Return Value:
new(Type)
returns *Type
(a pointer to the type).make(Type, ...)
returns Type
(a value of the type).new
new
when you need a pointer to a newly allocated zeroed value of a simple type.Example:
gotype Node struct {
Value int
Next *Node
}
func createNode(value int) *Node {
n := new(Node)
n.Value = value
return n
}
make
make
when you need to initialize slices, maps, or channels.Example:
gofunc createSlice() []int {
s := make([]int, 10) // Create a slice with length 10
return s
}
func createMap() map[string]int {
m := make(map[string]int) // Create an empty map
return m
}
func createChannel() chan int {
ch := make(chan int, 5) // Create a buffered channel with capacity 5
return ch
}
By understanding the differences between new
and make
and when to use each, you can allocate memory in Go efficiently and appropriately for different data types and use cases.