golang make和new

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

Go語言中的內建函數new和make是兩個用於記憶體配置的原語(allocation primitives)。對於初學者,這兩者的區別也挺容易讓人迷糊的。簡單的說,new只分配記憶體,make用於slice,map,和channel的初始化。

1. new函數

The new build-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 分配空間。傳遞給new 函數的是一個類型,不是一個值。傳回值是 指向這個新分配的零值的指標。

這是一個用來分配記憶體的內建函數,但是與C++不一樣的是,它並不初始化記憶體,只是將其置零。也就是說,new(T)會為T類型的新項目,分配被置零的儲存,並且返回它的地址,一個類型為*T的值。在Go的術語中,其返回一個指向新分配的類型為T的指標,這個指標指向的內容的值為零(zero value)。注意並不是指標為零。

Go語言中的對象沒有C++中的建構函式,如果用C來描述,Go中的new大概相當於:

T *t = (T*)malloc(sizeof(T))memset(t, 0, sizeof(T))

其實,上面的描可能也不是很準確,也許用*t=zerovalue更準確。因為對於不同的資料類型,零值的意義是完全不一樣的。比如,對於bool類型,零值為false;int的零值為0;string的零值是Null 字元串:

        b := new(bool)        fmt.Println(*b)        i := new(int)        fmt.Println(*i)        s := new(string)        fmt.Println(*s)

輸出:

false

0

注意最後有一個Null 字元串。

初始化

很多時候,零值並不是一個好主意,我們需要做一些初始化。考慮如下結構體:

type Rect struct {    x, y float64        width, height float64}

零值的Rect並沒有多大用處,我們以下方式進行初始化:

rect3 := &Rect{0, 0, 100, 200}

rect4 := &Rect{width: 100, height: 200}

Go語言中沒有C++中的建構函式,對象的建立一般交給一個全域的建立函數來完成:

func NewRect(x, y, width, height float64) *Rect {    return &Rect{x, y, width, height}}

注意,這裡與C/C++不同的是,返回一個局部變數的地址在Go語言中是絕對沒有問題的;變數關聯的儲存在函數返回之後依然存在。

更直接的說,在Go語言中,如果一個局部變數在函數返回後仍然被使用,這個變數會從heap,而不是stack中分配記憶體。

2. make

The make built-in function allocates and initializes an object(分配空間 + 初始化) of type slice, map or chan(only). Like new , the first arguement 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.
翻譯為:
內建函數 make 分配並且初始化 一個 slice, 或者 map 或者 chan 對象。 並且只能是這三種對象。 和 new 一樣,第一個參數是 類型,不是一個值。 但是make 的傳回值就是這個類型(即使一個參考型別),而不是指標。 具體的傳回值,依賴具體傳入的類型。

內建函數make(T, args)與new(T)的用途不一樣。它只用來建立slice,map和channel,並且返回一個初始化的(而不是置零),類型為T的值(而不是*T)。之所以有所不同,是因為這三個類型的背後引用了使用前必須初始化的資料結構。例如,slice是一個三元描述符,包含一個指向資料(在數組中)的指標,長度,以及容量,在這些項被初始化之前,slice都是nil的。對於slice,map和channel,make初始化這些內部資料結構,並準備好可用的值。

例如,

make([]int, 10, 100)

分配一個有100個int的數組,然後建立一個長度為10,容量為100的slice結構,該slice引用包含前10個元素的數組。對應的,new([]int)返回一個指向新分配的,被置零的slice結構體的指標,即指向值為nil的slice的指標。

var p *[]int = new([]int)       // allocates slice structure; *p == nil; rarely usefulvar v  []int = make([]int, 100) // the slice v now refers to a new array of 100 ints// Unnecessarily complex:這種做法實在是很蛋疼var p *[]int = new([]int)*p = make([]int, 100, 100)// Idiomatic:習慣的做法v := make([]int, 100)

make只用於map,slice和channel,並且不返回指標。要獲得一個顯式的指標,使用new進行分配,或者顯式地使用一個變數的地址。跟 new 不同的是,make 傳回型別的引用而不是指標。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.