SoFunction
Updated on 2025-03-05

A brief discussion on what is the difference between Golang's new and make

Difference: In go language, make and new are both memory allocations (on the heap), but make is only used for initialization of slices, maps and channels (non-zero values); new is used for type memory allocation, and the memory is set to zero. What makes returns is the reference type itself; whereas new returns a pointer to the type.

The operating environment of this article: Windows 10 system, GO 1.11.2, thinkpad t480 computer.

In Go, new and make are all allocation primitives used for memory allocation. Simply put, new only allocates memory, and make is used for initialization of slice, map, and channel.

new

The new(T) function is a built-in function that allocates memory.
We all know that for a variable already exists, its pointer can be assigned.

Example

var p int
var v *int
v = &p
*v = 11
(*v)

So, what if it weren't for a variable that already existed? Can it be assigned directly?

var v *int
*v = 8
(*v)

The result will report the following error

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x1 addr=0x0 pc=0x48df66]

How to solve it? Go provides new to initialize an address.

var v *int
v = new(int)
*v = 8
(*v)

Then let's analyze it

(*v)
(v) //<nil>
v = new(int) 
(*v)//
(v)//0xc00004c088

We can see that a pointer variable is initialized, whose value is nil, and the value of nil cannot be assigned directly. By new it returns a pointer to the newly allocated type int, the pointer value is 0xc00004c088, and the value of the content pointed to by this pointer is zero (zero value).

At the same time, it should be noted that the zero values ​​of different pointer types are different.

Example

type Name struct {
    P string
}
var av *[5]int
var iv *int
var sv *string
var tv *Name
 
av = new([5]int)
(*av) //[0 0 0 0 0 0]
iv = new(int)
(*iv) // 0
sv = new(string) 
(*sv) //
tv = new(Name)
(*tv) //{}

The above talks about how to assign values ​​after processing the common type new(). Here I will talk about how to assign values ​​after processing the compound type (array, slice, map, channel, etc.) and new().

Array example

var a [5]int
("a: %p %#v \n", &a, a)//a: 0xc04200a180 [5]int{0, 0, 0, 0, 0} 
av := new([5]int)
("av: %p %#v \n", &av, av)//av: 0xc000074018 &[5]int{0, 0, 0, 0, 0}
(*av)[1] = 8
("av: %p %#v \n", &av, av)//av: 0xc000006028 &[5]int{0, 8, 0, 0, 0}

silce example

var a *[]int
("a: %p %#v \n", &a, a) //a: 0xc042004028 (*[]int)(nil)
av := new([]int)
("av: %p %#v \n", &av, av) //av: 0xc000074018 &[]int(nil)
(*av)[0] = 8
("av: %p %#v \n", &av, av) //panic: runtime error: index out of range

map example

var m map[string]string
("m: %p %#v \n", &amp;m, m)//m: 0xc042068018 map[string]string(nil) 
mv := new(map[string]string)
("mv: %p %#v \n", &amp;mv, mv)//mv: 0xc000006028 &amp;map[string]string(nil)
(*mv)["a"] = "a"
("mv: %p %#v \n", &mv, mv)//The error will be reported here: assignment to entry in nil map

Channel example

cv := new(chan string)
("cv: %p %#v \n", &amp;cv, cv)//cv: 0xc000074018 (*chan string)(0xc000074020) 
//cv <- "good" //Can report invalid operation: cv <- "good" (send to non-chan type *chan string)

Through the above example, we see that the array is processed through new, and the array av initializes the zero value. Although the array is a composite type, it is not a reference type. Other silce, map, and channel types also belong to reference types. Go will initialize the reference type to nil, and nil cannot be assigned directly. And the memory cannot be allocated with new. Cannot directly assign value. So what would happen if you use make function to handle it?

make

Example

av := make([]int, 5)
("av: %p %#v \n", &amp;av, av) //av: 0xc000046400 []int{0, 0, 0, 0, 0}
av[0] = 1
("av: %p %#v \n", &amp;av, av) //av: 0xc000046400 []int{1, 0, 0, 0, 0}
mv := make(map[string]string)
("mv: %p %#v \n", &amp;mv, mv) //mv: 0xc000074020 map[string]string{}
mv["m"] = "m"
("mv: %p %#v \n", &amp;mv, mv) //mv: 0xc000074020 map[string]string{"m":"m"}
chv := make(chan string)
("chv: %p %#v \n", &amp;chv, chv) //chv: 0xc000074028 (chan string)(0xc00003e060)
go func(message string) {
   chv &lt;- message // Save message}("Ping!")
(&lt;-chv) // Get the message //"Ping!"close(chv)

make can not only open up a memory, but also initialize its zero value for the type of this memory.

It can also be used with new

Example

var mv *map[string]string
("mv: %p %#v \n", &mv, mv)//mv: 0xc042004028 (*map[string]string)(nil) 
mv = new(map[string]string)
(*mv) = make(map[string]string)
("mv: %p %#v \n", &mv, mv)//mv: 0xc042004028 &map[string]string{"a":"a"}

The pointer variable mv is allocated by new and assigned a memory address. Map is a reference type, its zero value is nil, use make to initialize the map, and then the variable can use * to assign values ​​to the pointer variable mv.

summary:

  • make and new are built-in functions used by golang to allocate memory, and allocate memory on the heap. make means allocating memory and initializing memory. new just clears the memory and does not initialize the memory.
  • What makes returns is the reference type itself; whereas new returns a pointer to the type.
  • make can only be used to allocate and initialize data of types slice, map, channel; new can allocate any type of data.

This is the end of this article about the difference between Golang's new and make. For more related Golang new make content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!