簡體   English   中英

在 Go 中使用 new vs var

[英]Use of new vs var in Go

你有一個帶參數的函數,一個指向類型的指針。

type bar struct{...}

func foo(arg *bar)

有什么區別:

var b bar
foo(&b)

b := new(bar)
foo(b)

使用 new 創建分配。

不,沒有區別,因為與 C 相反,Go 明確聲明您可以提供指向本地創建的變量的指針。

文檔中

請注意,與 C 不同,返回局部變量的地址是完全可以的; 與變量關聯的存儲在函數返回后仍然存在

兩者都應該表示指向使用相同默認值初始化的相同對象的相同指針。

規范確實提到:

type T struct { i int; f float64; next *T }
t := new(T)

以下成立:

t.i == 0
t.f == 0.0
t.next == nil

之后也是如此

var t T

還:

獲取復合文字的地址(§地址運算符)會生成一個指向該文字值的唯一實例的指針。

var pointer *Point3D = &Point3D{y: 1000}

一個分配一個 nil 指針,另一個分配一個指向零初始化結構的指針。 在鏈表樣式示例中:

type Node struct { 
  Data int
  Next *Node
}

以上述每種方式創建一個節點

var node1 = new(Node)
var node2 *Node

打印變量給出

&{0 <nil>}
<nil>

這意味着如果您嘗試這樣做

fmt.Println(node1.Data)
fmt.Println(node2.Data)

第一個將打印出 0,第二個將拋出一個 nil 指針取消引用異常和恐慌。

在某些情況下存在差異。 new(T) ,顧名思義,返回一個類型為 T 的新實例,而var b T是單個實例,一次且永遠(錯誤,實際上直到其生命周期結束 == 超出范圍,而不是可達...)。

考慮這個循環

var b bar
for i := 0; i < 10; i++ {
    foo(&b)
}

對比

var b *bar
for i := 0; i < 10; i++ {
    b = new(b)
    foo(b)
}

在后一種情況下,例如,如果foo將其arg存儲在某個容器中,則會導致 10 個bar實例存在,而前一種情況只有一個變量b

另一個區別在於性能。 變量b要么是完全靜態的全局變量,要么通常位於某個函數/方法調用記錄中的靜態已知偏移量(通常是堆棧幀的花哨名稱)。 new OTOH,如果沒有被編譯器優化,是一個內存分配器調用。 這樣的調用將花費一些非零時間。 如果在循環中進行並且實際上沒有必要,那么它可能會使某些代碼路徑明顯變慢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM