1 scope go shadowing lexical-scope
我找到的一些相关帖子:
还有许多用于变量范围和阴影的用例.
任何代码示例或答案将不胜感激.
小智 5
变量范围和阴影:
Go是使用块的词法范围:
- 预先声明的标识符的范围是Universe块.
- 表示在顶层(在任何函数之外)声明的常量,类型,变量或函数(但不是方法)的标识符的范围是包块.
- 导入包的包名称范围是包含导入声明的文件的文件块.
- 表示方法接收者,函数参数或结果变量的标识符的范围是函数体.
- 在函数内声明的常量或变量标识符的范围从ConstSpec或VarSpec(短变量声明的ShortVarDecl)结束开始,并在最内层包含块的末尾结束.
- 在函数内声明的类型标识符的范围从TypeSpec中的标识符开始,并在最内层包含块的末尾结束.
块中声明的标识符可以在内部块中重新声明.
虽然内部声明的标识符在范围内,但它表示内部声明声明的实体.包条款不是声明; 包名称不会出现在任何范围内.其目的是识别属于同一包的文件,并指定导入声明的默认包名.
Golang限制变量范围的方法(在语句中使用短手赋值):
package main
import "fmt"
func main() {
i := 10 //scope: main
j := 4
for i := 'a'; i < 'b'; i++ {
// i shadowed inside this block
fmt.Println(i, j) //97 4
}
fmt.Println(i, j) //10 4
if i := "test"; len(i) == j {
// i shadowed inside this block
fmt.Println(i, j) // i= test , j= 4
} else {
// i shadowed inside this block
fmt.Println(i, j) //test 40
}
fmt.Println(i, j) //10 4
}
Run Code Online (Sandbox Code Playgroud)当"我们需要更多字母"时,这是限制变量范围的好方法.
当您需要更多局部变量或范围时,这也很有效:
使用{和}配对:
优点:不需要额外的陈述,如if,for,...
package main
import "fmt"
func main() {
i := 1
j := 2
//new scope :
{
i := "hi" //new local var
j++
fmt.Println(i, j) //hi 3
}
fmt.Println(i, j) //1 3
}
Run Code Online (Sandbox Code Playgroud)限制变量范围的另一种方法是使用函数调用:
优点:范围限制,输入值类型参数可用作局部变量,
缺点:调用/返回时间和堆栈使用:如果未通过编译器优化
package main
import "fmt"
func fun(i int, j *int) {
i++ //+nice: use as local var without side effect
*j++ //+nice: intentionally use as global var
fmt.Println(i, *j) //11 21
}
func main() {
i := 10 //scope: main
j := 20
fun(i, &j)
fmt.Println(i, j) //10 21
}
Run Code Online (Sandbox Code Playgroud)另一种方法是遮蔽全局变量:
package main
import "fmt"
var i int = 1 //global
func main() {
j := 2
fmt.Println(i, j) //1 2
i := 10 //Shadowing global var
fmt.Println(i, j) //10 2
fun(i, j) //10 2
}
func fun(i, j int) {
//i := 100 //error: no new variables on left side of :=
//var i int = 100 //error: i redeclared in this block
fmt.Println(i, j) //10 2
}
Run Code Online (Sandbox Code Playgroud)