在golang中,make和new都是分配內存的,可是它們之間仍是有些區別的,只有理解了它們之間的不一樣,才能在合適的場合使用。golang
簡單來講,new只是分配內存,不初始化內存; 而make即分配又初始化內存。所謂的初始化就是給類型賦初值,好比字符爲空,整型爲0, 邏輯值爲false等。ide
先看下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
能夠看出,它的參數是一個類型,返回值爲指向該類型內存地址的指針,同時會把分配的內存置爲零,也就是類型的零值, 即字符爲空,整型爲0, 邏輯值爲falseui
看幾個new的示例this
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) //結構 fmt.Println(a, " ", *a) fmt.Println(s, " ",*s) fmt.Println(b, " ",*b) fmt.Println(i, " ",*i) fmt.Println(ps, " ", *ps)
輸出結果以下spa
&[0 0] [0 0] 0xc00000e1e0 0xc00001a07a false 0xc00001a090 0 &{ 0} { 0}
上面示例是基本的類型,再看下slice, map,chan這些用new咋操做指針
map操做 var mp *map[string]string mp = new(map[string]string) //*mp = make(map[string]string) //這行注掉會panic "panic: assignment to entry in nil map"" (*mp)["name"] = "lc" fmt.Println((*mp)["name"]) slice操做 var ms *[]string ms = new([]string) //*ms = make([]string,5) //這行注掉會pance "panic: runtime error: index out of range" (*ms)[0] = "lc" fmt.Println((*ms)[0])
上面能夠看出,silce、map、channel等類型屬於引用類型,引用類型初始化爲nil,nil是不能直接賦值的,也不能用new分配內存,還須要使用make來分配。code
看下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只能給slice,map,channel等初始化內存,它們返回的就是引用類型,那麼就不必返回指針了ci
看下make的一些示例
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 <-100 fmt.Println(<-ch)
make 僅用來分配及初始化類型爲 slice、map、chan 的數據。new 可分配任意類型的數據. new 分配返回的是指針,即類型 *Type。make 返回引用,即 Type. new 分配的空間被清零, make 分配空間後,會進行初始化.