Difference between make and new

Written byKalanKalan
💡

If you have any questions or feedback, pleasefill out this form

This post is translated by ChatGPT and originally written in Mandarin, so there may be some inaccuracies or mistakes.

In Go, there are two keywords make and new, which can easily be confused when you first start learning Go. Here’s a simple note to clarify their differences.

new

new can be used to initialize generics, and it returns a storage address. Therefore, we usually assign the type returned by new to a pointer variable. It’s particularly important to note that new automatically initializes the type with a zeroed value, meaning a string will be "", numbers will be 0, and channels, functions, maps, slices, etc., will be nil.

Due to this characteristic, if we perform the following operation on a map, we will encounter panic: assignment to entry in nil map.

func main() {
	people := new(map[string]string)
	p := *people
	p["name"] = "Kalan" // panic: assignment to entry in nil map
}

This happens because the initialized map is a nil map, unlike other primitive types which have default values.

When initializing with struct, you can also directly use & to indicate the address being pointed to; the two following methods yield the same result:

type Person struct {
  Name string
  Age  int
}

func main() {
    p := &Person{}
    p := new(Person)
}

The advantage of the first method is that you can set the Person fields based on the values you want to pass in, while new will directly fill all fields with zeroed values.

make

In contrast to new, make is used to initialize certain special types, such as channels, maps, and slices. Additionally, it’s important to note that make does not return a pointer; if you need a pointer, you should consider using something like new to initialize the type.

func main() {
    receiver := make(chan string) // initializes a channel but does not return a pointer
    person := make(map[string]string)
    people := make([]string, 100) // initializes a string array of length 100
}

It’s worth emphasizing again that make does not return a pointer! The following code will throw an error:

func main() {
	person := make(map[string]string)
	fmt.Println(*person) // invalid indirect of person
}

Conclusion

make and new are easily confused when you first start learning Go. Sometimes, when you need to pass a pointer as a parameter, you might inadvertently use make. Therefore, understanding the distinction between the two is crucial.

Further Reading

If you found this article helpful, please consider buying me a coffee ☕ It'll make my ordinary day shine ✨

Buy me a coffee