golang中,new和make的區別


在golang中,make和new都是分配內存的,但是它們之間還是有些區別的,只有理解了它們之間的不同,才能在合適的場合使用。

簡單來說,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

可以看出,它的參數是一個類型,返回值為指向該類型內存地址的指針,同時會把分配的內存置為零,也就是類型的零值, 即字符為空,整型為0, 邏輯值為false

看幾個new的示例

   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)

輸出結果如下

&[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來分配。

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只能給slice,map,channel等初始化內存,它們返回的就是引用類型,那么就沒必要返回指針了

看下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 分配空間后,會進行初始化.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM