The difference between new and make keywords in Go language

Original link: The difference between new and make keywords in Go language

This article introduces a very common interview question, how common is it? Maybe the opening remarks of many interviews start from this. That's the difference between the two built-in functions new and make.

In fact, the problem itself is not complicated. To put it simply, new only allocates memory, while make can only be used to initialize slice s, map s, and chan. Let’s introduce it in detail below.

new

new is a built-in function that allocates a piece of memory and returns a pointer to that memory.

Its function signature is as follows:

source code

// The new built-in function allocates memory. The first argument is a type,
// not a value, and the value returned is a pointer to a newly
// allocated zero value of that type.
func new(Type) *Type

As can be seen from the above code, the new function only accepts one parameter, which is a type, and returns a pointer to the memory address of that type.

At the same time, the new function will set the allocated memory to zero, which is the zero value of the type.

use

Use the new function to allocate memory space for variables:

p1 := new(int)
fmt.Printf("p1 --> %#v \n ", p1) //(*int)(0xc42000e250) 
fmt.Printf("p1 point to --> %#v \n ", *p1) //0

var p2 *int
i := 0
p2 = &i
fmt.Printf("p2 --> %#v \n ", p2) //(*int)(0xc42000e278) 
fmt.Printf("p2 point to --> %#v \n ", *p2) //0

The above codes are equivalent, new(int) initializes the allocated space to the zero value of int, which is 0, and returns the pointer of int, which is the same as directly declaring and initializing the pointer.

Of course, the new function can not only allocate space for the system’s default data types, but also user-defined types can use the new function to allocate space, as shown below:

type Student struct {
   name string
   age int
}
var s *Student
s = new(Student) //allocate space
s.name = "zhangsan"
fmt.Println(s)

This is the new function, which always returns a pointer of the type, and the pointer points to the memory address of the allocated type. It should be noted that the new function only allocates memory space, but does not initialize the memory space.

make

make is also used for memory allocation, but unlike new, it is only used for memory creation of slice, map, and chan, and the types it returns are these three types themselves, not their pointer types. Since these three types are themselves reference types, there is no need to return pointers to them.

Its function signature is as follows:

source code

// The make built-in function allocates and initializes an object of type
// slice, map, or chan (only). Like new, the first argument is a type, not a
// value. Unlike new, make's return type is the same as the type of its
// argument, not a pointer to it. The specification of the result depends on
// the type:
// Slice: The size specifies the length. The capacity of the slice is
// equal to its length. A second integer argument may be provided to
// specify a different capacity; it must be no smaller than the
// length, so make([]int, 0, 10) allocates a slice of length 0 and
// capacity 10.
// Map: An empty map is allocated with enough space to hold the
// specified number of elements. The size may be omitted, in which case
// a small starting size is allocated.
// Channel: The channel's buffer is initialized with the specified
// buffer capacity. If zero, or the size is omitted, the channel is
// unbuffered.
func make(t Type, size ...IntegerType) Type

It can be seen from the above code that the t parameter of the make function must be one of slice, map and chan, and the return value is also the type itself.

use

Let's use slice as an example:

var s1 []int
if s1 == nil {
    fmt.Printf("s1 is nil --> %#v \n ", s1) // []int(nil)
}

s2 := make([]int, 3)
if s2 == nil {
    fmt.Printf("s2 is nil --> %#v \n ", s2)
} else {
    fmt.Printf("s2 is not nill --> %#v \n ", s2)// []int{0, 0, 0}
}

The zero value of slice is nil, but after initialization with make, the slice content is filled with zero value of type int, such as: []int{0, 0, 0}.

map and chan are also similar, so I won't say more.

Summarize

Through the above analysis, the main differences between new and make are summarized as follows:

  1. make can only be used to allocate and initialize data of types slice, map and chan. new can allocate data of any type;
  2. The new allocation returns a pointer, the type *Type. make returns the type itself, Type;
  3. Space allocated by new is zeroed out. After make allocates space, it will be initialized;

The above is the whole content of this article. If you think it is not bad, please like, repost and follow. Thank you for your support.

Reference article:

Recommended reading:

Tags: Go Interview

Posted by nsr500rossi on Sun, 26 Mar 2023 18:39:02 +0530