Go 变量的简写声明(包括已经定义的变量)会分配新内存吗?

Go 变量的简写声明(包括已经定义的变量)会分配新内存吗?,go,Go,我有一个返回值user和err的函数。当我在作用域中调用它时,我已经有变量user,但没有变量err,所以编译器/linter告诉我使用:=运算符语法(我知道我可以在调用之前的某个地方用var声明声明err),使它看起来像这样: user:=user{“Name”} ... 用户,错误:=返回stwovalues()的函数 如果出错!=零{ ... 问题:在这种特定情况下,在user行中,err:=返回stwovalues的函数,是否会重新声明用户变量? p.S.我也明白,从实际结果来看,这对

我有一个返回值
user
err
的函数。当我在作用域中调用它时,我已经有变量
user
,但没有变量
err
,所以编译器/linter告诉我使用
:=
运算符语法(我知道我可以在调用之前的某个地方用
var
声明声明
err
),使它看起来像这样:

user:=user{“Name”}
...
用户,错误:=返回stwovalues()的函数
如果出错!=零{
...
问题:在这种特定情况下,在
user行中,err:=返回stwovalues的函数
,是否会重新声明用户变量?


p.S.我也明白,从实际结果来看,这对我来说并不重要,因为最终,在任何情况下,我都会在函数调用后得到具有正确数据的变量。此外,在我们的情况下,该变量将在堆栈中定义,这意味着即使有2个
我们,也不会涉及垃圾收集来清理它er
结构已初始化。

简而言之,是的,变量用户将被重新声明。从Go语言规范:

与常规变量声明不同,短变量声明可以重新声明最初在同一块中声明的变量。因此,重新声明只能出现在多变量短声明中。重新声明不会引入新变量;它只是为原始变量分配新值


有关更多详细信息,请参阅的规范。

是的,速记声明将重新定义它

主程序包
输入“fmt”
func main(){
i:=1
i、 x:=giveMeTwos()
fmt.Println(i,x)
}
func giveMeTwos()(int,int){
返回2,2
}

用户变量将用于存储函数结果,请参见下面的示例


是的,变量被重新声明,其值被重写。但它必须仍然具有相同的类型声明。重新声明实质上是一个赋值,并使用相同的堆栈内存

规范明确允许这样做,以使定义错误更简洁:

与常规变量声明不同,短变量声明可以重新声明最初在同一块中声明的变量(如果块是函数体,则参数列表)具有相同类型,并且至少有一个非空变量是新的。因此,重新声明只能出现在多变量短声明中。重新声明不会引入新变量;它只会为原始变量分配新值。 -

例如:

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
我认为用户变量不会被重新声明,但它的值当然会被覆盖。我已经通过检查变量的指针地址进行了测试,如下所示。正如您可能看到的,用于捕获变量地址的指针保持不变

剪下:

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
)和指针(
*up1
)访问同一对象。