gpt4 book ai didi

Golang 混合赋值和声明

转载 作者:IT老高 更新时间:2023-10-28 13:05:42 28 4
gpt4 key购买 nike

我开始使用 go 工作了几个星期,并且(再一次)我偶然发现了一些对我来说似乎很奇怪的东西:

// Not working
a := 1
{
a, b := 2, 3
}

// Works
a := 1
a, b := 2, 3

playground

我想同时分配两个变量。一个已经在上级范围内声明,另一个则没有。

它不起作用:编译器试图重新声明以前的变量。但是,如果在同一范围内声明此变量,则它可以正常工作。

这是为什么呢?

最佳答案

您所遇到的通常称为 "variable shadowing" .当您将 := 与内部范围内的任何变量一起使用时,包括在像 iffor 这样的语句中,尽管缺少大括号,一个新值和类型与该变量相关联:

n := "Example"
//Prints the string variable `n` to standard output and
// returns the number of bytes written in int variable `n` and
// an error indicator in error variable `err`.
if n, err := fmt.Println(n); err != nil {
panic(err)
} else {
fmt.Println(n, "bytes written")
}

//Prints the string variable `n` to standard output.
fmt.Printf("n = %q\n", n)

输出:

Example
8 bytes written
n = "Example"

有几种不同的方法可以解决此问题:

  • 在使用前声明您需要的变量,并使用 =
  • 进行正常赋值
  • 使用不同的变量名
  • 创建一个新范围并保存变量的值以供以后访问,根据需要使用带有 := 的变量名,并在范围结束之前恢复该值;使用不同的变量名通常更容易,因为无论如何您都在创建另一个变量

也可能出现相反的效果,即您在内部范围内声明了某些内容而没有意识到它:

if _, err := fmt.Println(n); err != nil {
panic(err)
} else {
fmt.Println(n, "bytes written")
}

//undefined: err
if _, err = fmt.Println(n); err != nil {
//undefined: err
panic(err)
}

同样,有几种不同的方法可以解决此问题:

  • 在使用前声明您需要的变量,并使用 =
  • 进行正常赋值
  • 将第一个 :=if 语句分开,这样变量就按预期声明了;这允许您在该范围的上下文以及包含它的任何范围内对该变量的所有其他实例使用 =
  • = 的所有实例更改为 := 以修复错误

请注意,当函数返回多个值时,您可能会在最后两种情况下遇到变量阴影问题,但可以按照上述说明解决。

Try both examples on the Go Playground.

您的最后一个示例说明了声明和初始化新变量 b 的组合,同时还为现有变量 a 赋值。没有创建新的范围,因此您不会隐藏原始变量 a,您可以 verify by printing the address of a after each assignment (but before the next declaration/assignment) :

a := 1
fmt.Println(&a)
a, b := 2, 3
fmt.Println(&a)
a = b // avoids a "declared but not used" error for `b`

当然,如果你没有声明 b,那么你会从编译器收到一个错误,即 := 左侧没有新变量> 对于第二个声明,这是一种迂回的说法,表示您试图在同一范围内声明 a 两次。

请注意,如果仔细应用这个想法,也可以用来查找被遮蔽的变量。例如,您示例中的“不工作”代码将 print different addresses for a ,取决于内部范围内的 a 是否已经声明:

a := 1
{
fmt.Println(&a) // original `a`
a, b := 2, 3
fmt.Println(&a) // new `a`
a = b // avoids a "declared but not used" error for `b`
}
fmt.Println(&a) // original `a`

关于Golang 混合赋值和声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37351022/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com