gopl-zh.github.com/ch2/ch2-03-3.md

1.9 KiB
Raw Blame History

2.3.3. new函數

另一個創建變量的方法是調用用內建的new函數。表達式new(T)將創建一個T類型的匿名變量初始化爲T類型的零值然後返迴變量地址返迴的指針類型爲*T

p := new(int)   // p, *int 類型, 指向匿名的 int 變量
fmt.Println(*p) // "0"
*p = 2          // 設置 int 匿名變量的值爲 2
fmt.Println(*p) // "2"

用new創建變量和普通變量聲明語句方式創建變量沒有什麽區别除了不需要聲明一個臨時變量的名字外我們還可以在表達式中使用new(T)。換言之new函數類似是一種語法糖而不是一個新的基礎概念。

下面的兩個newInt函數有着相同的行爲

func newInt() *int {
	return new(int)
}

func newInt() *int {
	var dummy int
	return &dummy
}

每次調用new函數都是返迴一個新的變量的地址因此下面兩個地址是不同的

p := new(int)
q := new(int)
fmt.Println(p == q) // "false"

當然也可能有特殊情況如果兩個類型都是空的也就是説類型的大小是0例如struct{}[0]int, 有可能有相同的地址依賴具體的語言實現譯註請謹慎使用大小爲0的類型因爲如果類型的大小位0好話可能導致Go語言的自動垃圾迴收器有不同的行爲具體請査看runtime.SetFinalizer函數相關文檔)。

new函數使用常見相對比較少因爲對應結構體來説可以直接用字面量語法創建新變量的方法會更靈活§4.4.1)。

由於new隻是一個預定義的函數它併不是一個關鍵字因此我們可以將new名字重新定義爲别的類型。例如下面的例子

func delta(old, new int) int { return new - old }

由於new被定義爲int類型的變量名因此在delta函數內部是無法使用內置的new函數的。