【學習筆記】make 和 new 關鍵字的區別

icecho發表於2019-09-18

Go 語言中 new 和 make 是兩個內建函式,主要用來初始化型別,分配記憶體空間,但是它們之間有一些不同。

宣告一個變數

var a int
var b string

這裡我們使用var關鍵字,宣告兩個變數,然後就可以在程式中使用。當我們不指定變數的預設值的時候呢,這些變數的預設值是它所屬型別的零值。比如上面的int型它的零值為 0string的零值為"",引用型別的零值為nil

接下來嘗試一下定義引用型別。

package main

import "fmt"

func main() {
    var a *int
    *a = 10
    fmt.Println(*a)
}

執行一下這個程式,它會發生 panic,原因是:

panic: runtime error: invalid memory address or nil pointer dereference

從這我們可以看出,如果是一個引用型別,我們不僅要宣告它,還要為它分配記憶體空間,否則我們賦值的 10 就無處安放。值型別的宣告不需要我們分配記憶體空間,因為已經預設給我們分配好啦。

new 關鍵字

我們使用 new 關鍵字來改寫一下上面的 demo

package main

import "fmt"

func main() {
     var a *int
    a = new(int)
    *a = 10
    fmt.Println(*a)
}

我們可以執行成功,並且成功列印出 10。下面貼出 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

簡單翻譯: 此內建函式用於分配記憶體,第一個引數接收一個型別而不是一個值,函式返回一個指向該型別記憶體地址的指標,同時把分配的記憶體置為該型別的零值。

make 關鍵字

make 也是用於分配記憶體,與 new 不同的是,它一般只用於 chanmapslice的初始化,並且直接返回這三種型別本身。以下是 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

從宣告也能看出,返回的還是該型別。

兩者異同

  • new 和 make 都是用於記憶體的分配。
  • make 只用於 chan,map,slice 的初始化。
  • new 用於給型別分配記憶體空間,並且置零。
  • make 返回型別本身,new 返回指向型別的指標。

Hello。

相關文章