go学习笔记(15)代码块、影子变量
代码块
go语言允许我们在很多地方定义变量,这些发生定义行为的地方可以称为代码块。
宇宙块(universe block ):包含程序中的全部代码。
包代码块(package block):go语言中一个文件夹就是一个包。简单理解就是文件夹下各个文件中代码的集合。我们可以用import
来导包。
文件代码块(file block):单个文件中的代码集合。
局部代码块(block):一般一对大括号{}
中的代码就是一个代码块(显式代码块),也有一些代码块不在一对大括号中(隐式代码块)。
我们可以在内层代码块中访问外层代码块中的变量,如果内层代码块和外层代码块中的变量名一样的时候,外层代码块中的变量就会被遮盖,我们就只能访问到内层代码中的变量,内层代码块中的变量就成为了影子变量。
影子变量
看下面这段代码,
输出的结果是:
1 | inner: 10 |
第1次读取的是外部代码块中的x,第2次读取的是内部代码块中创建的变量x,此时在外部代码块的x已经被遮盖不能再被访问到。
影子变量是go里面比较容易写出bug的一个点。go语言的:=
用起来实在是太方便了,有时候随手一写就会把赋值=
写成创建新变量:=
。
在goland中,内层代码块中的同名变量会用翠绿色标记出来提醒编写者该变量是影子变量。
当我们通过:=
对多个变量进行操作,同时包含赋值和声明的时候,特别容易出错,此时最好直接用var
来声明变量。
输出:
1 | 1 2 |
虽然外层代码块中已经有了x变量,:=
还是为我们创建了一个新的x变量遮盖了外部的x变量。
除了对外层代码块中变量的遮盖外,go语言中还有一个比较容量出错的地方在于go语言只有25个关键字,包名、类型名、内置函数等都不是关键字,它们都是宇宙块中的预定义的标识符。
这样一旦我们不小心声明了一个局部变量用了相同的名字,那在接下来的局部代码块中原来的值就会被遮盖。
1 | fmt.Println(true) |
输出:
1 | true |