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", &m, m)//m: 0xc042068018 map[string]string(nil) mv := new(map[string]string) ("mv: %p %#v \n", &mv, mv)//mv: 0xc000006028 &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", &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", &av, av) //av: 0xc000046400 []int{0, 0, 0, 0, 0} av[0] = 1 ("av: %p %#v \n", &av, av) //av: 0xc000046400 []int{1, 0, 0, 0, 0} mv := make(map[string]string) ("mv: %p %#v \n", &mv, mv) //mv: 0xc000074020 map[string]string{} mv["m"] = "m" ("mv: %p %#v \n", &mv, mv) //mv: 0xc000074020 map[string]string{"m":"m"} chv := make(chan string) ("chv: %p %#v \n", &chv, chv) //chv: 0xc000074028 (chan string)(0xc00003e060) go func(message string) { chv <- message // Save message}("Ping!") (<-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!