这两个函数都用于分配内存,但两者之间仍然有一些差异。本文介绍它们之间的差异,以及各自的应用场景。简言之,new分配内存但不初始化内存;make分配内容并初始化内存,所谓初始化即给变量赋初始值。举例,字符串为空,整型为0,布尔变量为false。

new

首先看下new函数定义:

// 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

new函数参数是类型,返回值是指针,指向该类型的内存地址,分配的内存被设为零值,即该类型的零值,就是说字符串为空,整型为0,布尔变量为false等。

下面请看示例:

package main import ( "fmt" ) func main() { type P struct { Name string Age int } var a *[2]int var s *string var b *bool var i *int var ps *P a = new([2]int) s = new(string) b = new(bool) i = new(int) ps = new(P) //structure fmt.Println(a, " ", *a) fmt.Println(s, " ", *s) fmt.Println(b, " ", *b) fmt.Println(i, " ", *i) fmt.Println(ps, " ", *ps) }

输出结果:

&[0 0] [0 0] 0xc00004c250 0xc00001a098 false 0xc00001a0c0 0 &{ 0} { 0}

上面是基本类型,下面看slice、map、Chan,new操作的结果进行对比:

package main import ( "fmt" ) func main() { //map operation var mp *map[string]string mp = new(map[string]string) //*mp = make(map[string]string) // if previous line is omitted, it will pan "Pan: assignment to entry in nil map" (*mp)["name"] = "lc" fmt.Println((*mp)["name"]) //slice operation var ms *[]string ms = new([]string) //*ms = make([]string, 5) // if previous line is deleted, it will "panic: runtime error: index out of range" (*ms)[0] = "lc" fmt.Println((*ms)[0]) }

我们看到slice,map,channel以及其他的引用类型初始化时为nil,nil不能被直接赋值。new也不能分配内存,还需要make分配内存。

make

首先查看make函数的定义:

// 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. For example, make([]int, 0, 10) allocates an underlying array // of size 10 and returns a slice of length 0 and capacity 10 that is // backed by this underlying array. // 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

make函数返回值与参数类型一致,而不是指针,因为make仅初始化slice,map,channel等的内存,而这些类型是引用类型,不需要返回指针。请看示例:

package main import ( "fmt" ) func main() { mm := make(map[string]string) mm["name"] = "lc" fmt.Println(mm["name"]) mss := make([]int, 2) mss[0] = 100 fmt.Println(mss[0]) ch := make(chan int, 1) ch