SoFunction
Updated on 2025-03-04

Deeply understand the difference between Golang make and new and its implementation principles

Preface

In Go, there are two similar built-in functions, namelynewandmakeMethods, both can be used to allocate memory, so what is the difference? For beginners, they may find it a little confused, especially when they are not well-known.panic, Let’s analyze the differences between the two from the bottom level. Interested friends can refer to it, and I hope it will be helpful to everyone.

Use of new

newTypes can be created and initialized.Its return value is a pointer reference of the type created, this is one of the differences from make functions. Let's take a look at it through a sample code:

func main() {
    var a *int
    (a) // nil
    *a = 123 //panic
    (a)
}

From the above code, we can see that when we passvarDeclare a variable and print itnil, when we assign a value to this variable, we will report an error:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x10a9043]

In summary, we can summarize that initializing a pointer variable, whose value is nil, and the value of nil cannot be assigned directly.

Since we know that there is no memory allocated for it, then we can allocate one using new. After the code is modified:

func main() {
    var a *int
	a = new(int)
    ("a type is :%T,a point value is :%v,a value is:%v,a size is: %v\n", a, a, *a, (a))
	//a type is :*int,a point value is :0xc00001a0a0,a value is:0,a size is: 8
    *a = 123
    ("a type is :%T,a point value is :%v,a value is:%v,a size is: %v\n", a, a, *a, (a))
    //a type is :*int,a point value is :0xc00001a0a0,a value is:123,a size is: 8
}

Through the above examples we can seenewIt returns a pointer to the newly allocated type int, the pointer value is 0xc00001a0a0, and the value of the content pointed to by this pointer is zero (zero value). Memory allocation can be assigned through new.

Underlying implementation

newThe signature of the function is as follows:

func new(Type) *Type

TypeIt refers to the type of variable, you can seenewA pointer to that type will be returned based on the variable type.

The underlying call isApply for memory space:

func newobject(typ *_type)  {
	return mallocgc(, typ, true)
}

By callingmallocgcOn the stack, the size of the structure will only apply for a piece of memory space, and will not apply for a pointer type in the structure.

Use of make

makeFunctions are also used for memory allocation, butnewDifferent, only supportedslicemapchannelMemory creation of three data types, whose return value is the created type itself, rather than a new pointer reference.

Note: These three types are reference types, so there is no need to return their pointers. They must be initialized, but not set to zero value.

Let's take a look at it with an example:

func test()  {
	var s *[]int
	("s: %p %#v \n", &s, s) //s: 0xc00000e028 (*[]int)(nil)
	s = new([]int)
	("s: %p %#v \n", &s, s) //s: 0xc00000e028 &[]int(nil)
	(*s)[0] = 8
	("s: %p %#v \n", &s, s) //panic: runtime error: index out of range [0] with length 0
}

We first use new to initialize the reference type to nil, and nil cannot be assigned directly. Change it to make.

func test()  {
	var s = make([]int, 5)
	("s: %p %#v \n", &s, s) //s: 0xc00000c060 []int{0, 0, 0, 0, 0}
	s[0] = 8
	("s: %p %#v \n", &s, s) //s: 0xc00000c060 []int{8, 0, 0, 0, 0}
}

Through the above example output, we can see that make can not only open up a memory, but also initialize its zero value for the type of this memory. Similarly, formapchannelThe same effect is also true.

Underlying implementation

makeThe signature of the function is as follows:

func make(t Type, size ...IntegerType) Type

You can see that what makes returns is the compound type itself.

When making is applying for slice memory, the underlying call is

func makeslice(et *_type, len, cap int)  {
	mem, overflow := (, uintptr(cap))
	if overflow || mem > maxAlloc || len < 0 || len > cap {
		mem, overflow := (, uintptr(len))
		if overflow || mem > maxAlloc || len < 0 {
			panicmakeslicelen()
		}
		panicmakeslicecap()
	}

	return mallocgc(mem, et, true)
}

Can seemakesliceThe request for the underlying memory call is alsomallocgc, first passMulUintptraccording toCapacity capMultiply byCalculate the required memory size and then allocate the required memory.makeformapandchannelThe underlying memory layers areruntime.makemap_small, also calledmallocgc

Summarize

  • make and new are 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 deeply understanding the difference and implementation principles of Golang make and new. For more relevant content on the difference between Golang make new, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!