簡體   English   中英

變量的速記聲明,涉及已經定義的變量,會分配新的內存嗎?

[英]Will shorthand declaration of variable, involving already defined one, allocate new memory?

我有一個返回值usererr的函數。 當我在范圍內調用它時,我已經有變量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/eHHycX4p16j

我認為用戶變量沒有被重新聲明,但當然它的值被覆蓋了。 我已經通過檢查變量的指針地址進行了測試,如下所示。 如您所見,用於捕獲變量地址的指針保持不變。

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.

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