天天看點

golang make()和new()差別

使用場景

package main

import "fmt"

func main() {
    var a *string
    *a ="hello world"
    fmt.Println(*a)
}
           

執行上面的結果會報下面的錯誤:

panic: runtime error: invalid memory address or nil pointer dereference
[signal  code= addr= pc=]

goroutine  [running]:
main.main()
        D:/project/test1.go: +
exit status 
           

出現這個問題的原因是:對于引用類型的變量,不僅要聲明它,還要為它配置設定記憶體空間。而值類型的變量,預設已經幫我們配置設定好了。那麼如何實作記憶體配置設定,就需要用到Go的兩個内建函數:new()和make()。

func new(Type) *Type函數

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

new(T)為每個新的類型T配置設定一片記憶體,傳回一個指向類型為T的、值為零的指針,它适用于值類型:如數組和結構體。

package main

import "fmt"

func main() {
    var slice1 = new([]string)
    slice1 = &[]string{"hello", "world"}
    fmt.Println(slice1)
}
           

func make(t Type, size …IntegerType) Type函數

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

make(T)配置設定記憶體并初始化類型T,它隻适用3種内建的引用類型:切片、map和channel。

package main

import "fmt"

func main() {
    var slice1 = make([]string,)
    slice1 = append(slice1, "hello")
    slice1 = append(slice1, "world")
    fmt.Println("slice1 :", slice1)
}
           

上面代碼運作的結果為:

slice1 : [ hello world]

。在元素值hello、world之前還有兩個空字元串,使用append()函數是在原切片的尾部添加内容,是以make()函數初始化了一個長度為2,元素值為0的切片。

是以,當你使用append函數為make()函數建立的切片追加元素時,切片的長度應當設定為0。否則切片中就會包含空元素。

二者異同

兩者都是記憶體的配置設定,但是make()隻用于slice、map和channel的初始化,而new()函數适用于任何類型的記憶體配置設定。另外,make()傳回的是這三個引用類型本身,而new()傳回的是指向類型的指針。