代码块与作用域
代码块
代码块一般就是一个由花括号括起来的区域,里面可以包含表达式和语句。
一个代码块可以有若干个子代码块;但对于每个代码块,最多只会有一个直接包含它的代码
块(后者可以简称为前者的外层代码块)。
作用域
上述我们对代码块的划分,也间接地决定了程序实体的作用域。
一个程序实体的作用域总是会被限制在某个代码块中,而这个作用域最大的用处,就是对程序实体的访问权限的控制。
下面我们通过一个例子,来探究一下代码块与作用域的关系:
如下代码中会涉及四个代码块,整个程序就是一个全域代码块。
package main //main包代码块
import "fmt"
var block = "package"
func main() { //main函数代码块
block := "function"
{ //局部代码块
block := "inner"
fmt.Printf("The block is %s.\n", block)
}
fmt.Printf("The block is %s.\n", block)
}
Result
C:\Users\Aylee\AppData\Local\Temp\GoLand\___go_build_GoSync_src_q3.exe
The block is inner.
The block is function.
从上面的结果来看我们可以得出以下3个结论:
- 代码引用变量的时候总会最优先查找当前代码块中的那个变量。
- 如果当前代码块中没有声明以此为名的变量,那么程序会沿着代码块的嵌套关系,从直接包含当前代码块的那个代码块开始,一层一层地查找, 找不到则会报错。
- 内层代码块中的同名变量不能被块外访问到。
不同代码块中的重名变量与变量重声明中的变量区别
- 变量重声明中的变量一定是在某一个代码块内的。注意,这里的“某一个代码块内”并不包含它的任何子代码块,否则就变成了“多个代码块之间”。而可重名变量指的正是在多个代码块之间由相同的标识符代表的变量。
- 变量重声明是对同一个变量的多次声明,这里的变量只有一个。而可重名变量中涉及的变量肯定是有多个的。
- 不论对变量重声明多少次,其类型必须始终一致,具体遵从它第一次被声明时给定的类型。而可重名变量之间不存在类似的限制,它们的类型可以是任意的。
- 如果可重名变量所在的代码块之间,存在直接或间接的嵌套关系,那么它们之间一定会存在“屏蔽”的现象。但是这种现象绝对不会在变量重声明的场景下出现。