为了账号安全,请及时绑定邮箱和手机立即绑定

变量的简写声明,涉及已经定义的变量,会分配新的内存吗?

变量的简写声明,涉及已经定义的变量,会分配新的内存吗?

Go
慕姐4208626 2022-04-26 19:52:29
我有一个返回值user和err. 当我在范围内调用它时,我已经有 variable user,但没有 variable err,所以编译器/linter 告诉我使用:=运算符语法(我知道我可以err在此调用之前的某个地方var声明),使其看起来像这样:user := User{"Name"}...user, err := functionThatReturnsTwoValues()if err != nil {...问题:在这种特定情况下,在行user, err := functionThatReturnsTwoValues中,用户变量会被重新声明吗?PS我也了解到,从实际结果来看,这对我来说并不重要,因为最后,无论如何在函数调用后我都会得到具有正确数据的变量。User此外,在我们的例子中,该变量将在堆栈中定义,这意味着即使初始化了 2 个结构,也不会涉及垃圾收集来清理它。
查看完整描述

3 回答

?
一只斗牛犬

TA贡献1784条经验 获得超2个赞

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

https://play.golang.org/p/eHHycX4p16j


查看完整回答
反对 回复 2022-04-26
?
慕斯709654

TA贡献1840条经验 获得超5个赞

我认为用户变量没有重新声明,但它的值当然被覆盖了。我已经通过检查变量的指针地址进行了测试,如下所示。如您所见,用于捕获变量地址的指针保持不变。


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


查看完整回答
反对 回复 2022-04-26
?
狐的传说

TA贡献1804条经验 获得超3个赞

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


规范明确允许这样做,以使定义 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


查看完整回答
反对 回复 2022-04-26
  • 3 回答
  • 0 关注
  • 169 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信