SoFunction
Updated on 2025-03-05

Detailed explanation of the difference between make and new in Go language

Write in front

AlthoughmakeandnewBoth can be used to initialize data structures, but the two can initialize structure types are quite different;makeIn Go language, it can only be used to initialize three types in languages: slice, map, chan

slice := make([]int, 0, 100)
hash := make(map[int]bool, 10)
ch := make(chan int, 5)

These basic types are provided by the language. We have actually introduced their initialization process and principles in the previous chapters, but here we still need to remind readers that these three return different types of data structures:

  • sliceis a containingdatacapandlenofStructure
  • hashIt's a pointhmapStructuralpointer
  • chIt's a pointhchanStructuralpointer

And another keyword used to initialize the data structurenewThe function of   is actually very simple. It just takes a type as a parameter and returns a pointer to this type:

i := new(int)

var v int
i := &v

The two different initialization methods in the above code snippet are actually equivalent, and they will create a pointer.intPointer of zero value.

Here we have a certain understanding of the use of these two different keywords in the Go language:makeUsed to create built-in data structures such as slices, hash tables and pipelines.newUsed to allocate and create a pointer to the corresponding type.

Implementation principle

Next we will introduce it separatelymakeandnewIn the specific process of initializing different data structures, we will understand the principles of these two keywords from two different stages, the compilation period and the runtime, but since it has been introduced in detail beforemakeThe implementation principle, so we will focus onnewAnalyze its implementation from the source code level of Go language.

make

We have actually talked about it in the previous chapter.makeIn the specific process of creating arrays and slices, hash tables and channels, so in this section, we will simply mention themmakeRelated data structure initialization principle.

During the type checking stage during compilation, the Go language will actually representmakeKeywordOMAKEThe node is converted to the node according to the parameter typeOMAKESLICEOMAKEMAPandOMAKECHANThree different types of nodes, these nodes will eventually call different runtime functions to initialize the data structure.

new

Built-in functionsnewThe SSA code generation phase will pass during the compilation periodcallnewThe processing of the function. If the requested type is 0, a null pointer will be returned.zerobaseVariables, when encountering other situations, will convert keywords intonewobject

func callnew(t *) *Node {
    if () {
        yyerror("%v is go:notinheap; heap allocation disallowed", t)
    }
    dowidth(t)

    if () == 0 {
        z := newname(("zerobase"))
        (PEXTERN)
         = t
        return typecheck(nod(OADDR, z, nil), ctxExpr)
    }

    fn := syslook("newobject")
    fn = substArgTypes(fn, t)
    v := mkcall1(fn, (t), nil, typename(t))
    (true)
    return v
}

It should be mentioned that even if the current variable is usedvarInitialization may be converted tonewobjectThe function call and request memory on the heap:

func walkstmt(n *Node) *Node {
    switch  {
    case ODCL:
        v := 
        if () == PAUTOHEAP {
            if prealloc[v] == nil {
                prealloc[v] = callnew()
            }
            nn := nod(OAS, , prealloc[v])
            (true)
            nn = typecheck(nn, ctxStmt)
            return walkstmt(nn)
        }
    case ONEW:
        if  == EscNone {
            r := temp(())
            r = nod(OAS, r, nil)
            r = typecheck(r, ctxStmt)
            (r)
            r = nod(OADDR, , nil)
            r = typecheck(r, ctxExpr)
            n = r
        } else {
            n = callnew(())
        }
    }
}

Of course, this is not absolute. If the currently declared variables or parameters do not need to "survive" outside the current scope, then they will not be initialized on the heap, but will be initialized in the stack of the current function and destroyed with the end of the function call.

newobjectThe job of a function is to get the size of the passed type and call itmallocgcApply for a suitable memory space on the heap and return a pointer to this memory space:

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

mallocgcThe implementation of the function has about 200 lines of code. I will not analyze it in detail in this section. We will introduce the memory management mechanism of Go in detail in the following chapters.

Summarize

At the end, let’s briefly summarize the Go languagemakeandnewThe implementation principle of keywords,makeThe main function of keywords is to create built-in data structures such as slices, hash tables and Channels, andnewThe main function is to apply for a piece of memory space for the type and return a pointer to this piece of memory.

refer to

[1]How the master learns the Go language make and new

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