有人可以给我一个关于我何时以及为什么要在函数中使用匿名范围的解释? (我不确定它实际上叫什么)。
我已经获得了一些遗留代码来维护,而且一些函数包含了我之前从未见过的“范围”:
(为演示目的而简化)
func DoSomething(someBoolValue bool) string {
if someBoolValue {
// do some stuff
return "yes"
}
{
// weird scope code
}
return "no"
}
我创建了一个Go Playground来演示一些实际代码(会引发错误)。
答案 0 :(得分:3)
它被称为变量范围和阴影:
Go使用块进行词法作用:
1 - 预先声明的标识符的范围是Universe块 2 - 标识符的范围,表示常量,类型,变量或 在顶层声明的函数(但不是方法)(在任何函数之外) 是包块。
3 - 导入的包名称的范围 package是包含导入的文件的文件块 声明。
4-表示方法接收者的标识符的范围, 函数参数或结果变量是函数体 5-在函数内声明的常量或变量标识符的范围 从ConstSpec或VarSpec的末尾开始(简称ShortVarDecl) 变量声明)并在最里面包含的末尾结束 块。
6-在函数内声明的类型标识符的范围 从TypeSpec中的标识符开始,到结尾处结束 最里面的包含块。块中声明的标识符可以是 在内部区域重新宣布。而内在的标识符 声明在范围内,它表示由内部声明的实体 声明。包条款不是声明;包名称没有 出现在任何范围内。其目的是识别属于的文件 相同的包并指定导入的默认包名称 声明。
您的工作示例代码:
package main
import (
"fmt"
)
func main() {
i := 10
{
i := 1
fmt.Println(i) // 1
}
fmt.Println(i) // 10
}
输出:
1
10
答案 1 :(得分:1)
{}
形成语法块。每个块定义一个新范围。这些块与您在if
和for
中使用的块相同。
关于您的代码,我猜它们主要是出于可读性目的而存在。您可以重用或隐藏在封闭范围中定义的变量,以利用可能更清楚地声明代码意图的变量名称。
除此之外,它们还可用于对一堆相关语句进行分组,同样是为了便于阅读。
要了解他们的行为,请参阅@ Amd的答案。