![](/img/trans.png)
[英]Does golang allocate new memory when reassign a new struct to a variable?
[英]Will shorthand declaration of variable, involving already defined one, allocate new memory?
我有一個返回值user
和err
的函數。 當我在范圍內調用它時,我已經有變量user
,但沒有變量err
,所以編譯器/linter 告訴我使用:=
運算符語法(我知道我可以在此調用之前的某個地方使用var
聲明聲明err
),使其成為看起來像這樣:
user := User{"Name"}
...
user, err := functionThatReturnsTwoValues()
if err != nil {
...
問題:在這種特定情況下,在user, err := functionThatReturnsTwoValues
,會重新聲明 user 變量嗎?
PS我也明白,從實際結果來看,這對我來說並不重要,因為最終,無論如何,在函數調用后我都會有帶有正確數據的變量。 此外,在我們的案例中,該變量將在堆棧中定義,這意味着即使初始化了 2 個User
結構,也不會涉及垃圾收集來清理它。
用戶變量將用於存儲函數的結果,請參見下面的示例
我認為用戶變量沒有被重新聲明,但當然它的值被覆蓋了。 我已經通過檢查變量的指針地址進行了測試,如下所示。 如您所見,用於捕獲變量地址的指針保持不變。
https://play.golang.org/p/bj3QwSgCCiG
剪斷:
func main() {
user := User{"Name"}
up1 := &user
user, err := functionThatReturnsTwoValues()
up2 := &user
if err == nil {
fmt.Printf("User: %v \n", user)
fmt.Printf("Pointer check : up1 ?= up2 --> %t [up1=%p, up2=%p]\n", up1 == up2, up1, up2)
fmt.Printf("Value check : *up1 ?= *up2 --> %t \n", *up1 == *up2)
}
}
輸出是:
User: {Name2}
Pointer check : up1 ?= up2 --> true [up1=0x40c138, up2=0x40c138]
Value check : *up1 ?= *up2 --> true
簡而言之,是的,變量 user 將被重新聲明。 來自 Go 語言規范:
與常規變量聲明不同,簡短的變量聲明可能會重新聲明變量,前提是它們最初是在同一塊中較早地聲明的。 因此,重新聲明只能出現在多變量短聲明中。 重新聲明不會引入新變量; 它只是為原始值分配一個新值。
有關更多詳細信息,請參閱短變量聲明的規范。
是的,變量被重新聲明並且它的值被覆蓋。 但它仍然必須具有相同的類型聲明。 重新聲明本質上歸結為賦值,並使用相同的堆棧內存。
規范明確允許這樣做,以使諸如定義 err 之類的情況更整潔:
與常規變量聲明不同,短變量聲明可以重新聲明變量,前提是它們最初在同一塊(如果塊是函數體,則為參數列表)中先前聲明的具有相同類型,並且至少有一個非空變量是新的。 因此,重新聲明只能出現在多變量短聲明中。 重新聲明不會引入新變量; 它只是為原始值分配一個新值。 - https://golang.org/ref/spec#Short_variable_declarations
例如:
var user User
user, err := fetchUser() // OK: user redeclared but new err variable declared
user, err := fetchUser() // Bad: user and err variable redeclared, but no new variables declared
user, err = fetchUser() // OK: No declarations, only assignments
是的,速記聲明將重新定義它。
package main
import "fmt"
func main() {
i := 1
i, x := giveMeTwos()
fmt.Println(i, x)
}
func giveMeTwos() (int, int) {
return 2, 2
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.