变量声明:静态语言有别于动态语言的重要特征
- 变量所绑定的内存区域是要有一个明确的边界的。也就是说,通过这样一个变量,我们究竟可以操作 4 个字节内存还是 8 个字节内存,又或是 256 个字节内存,编程语言的编译器或解释器需要明确地知道。
- 动态语言(比如 Python、Ruby 等)的解释器可以在运行时通过对变量赋值的分析,自动确定变量的边界。并且在动态语言中,一个变量可以在运行时被赋予大小不同的边界。
- 静态类型语言编译器必须明确知道一个变量的边界才允许使用这个变量,但静态语言编译器又没能力自动提供这个信息,这个边界信息必须由这门语言的使用者提供,于是就有了“变量声明”。
- 通过变量声明,语言使用者可以显式告知编译器一个变量的边界信息。
- 在具体实现层面呢,这个边界信息由变量的类型属性赋予。
- 作为身处静态编程语言阵营的 Go 语言,它沿袭了静态语言的这一要求:使用变量之前需要先进行变量声明。
Go 语言的变量声明方法
- 在 Go 语言中,如果你没有显式为变量赋予初值,Go 编译器会为变量赋予这个类型的零值,通用的变量声明方法是这样的:
- 除了单独声明每个变量外,Go 语言还提供了变量声明块(block)的语法形式,可以用一个 var 关键字将多个变量声明放在一起:
var ( a int = 128 b int8 = 6 s string = "hello" c rune = 'A' t bool = true )
- Go 语言还支持在一行变量声明中同时声明多个变量:
var a, b, c int = 5, 6, 7
。 - 这样的多变量声明同样也可以用在变量声明块中:
var ( a, b, c int = 5, 6, 7 c, d, e rune = 'C', 'D', 'E' )
- 为了给开发者带来更好的使用体验,Go 语言还提供了两种变量声明的“语法糖”:
- 省略类型信息的声明
- 在通用的变量声明的基础上,Go 编译器允许我们省略变量声明中的类型信息,它的标准范式是“var varName = initExpression”。
- Go 编译器会根据右侧变量初值自动推导出变量的类型,并给这个变量赋予初值所对应的默认类型。
- 结合多变量声明,我们可以使用这种变量声明“语法糖”声明多个不同类型的变量。
- 短变量声明
- 使用短变量声明时,我们甚至可以省去 var 关键字以及类型信息,它的标准范式是“varName := initExpression”。
- 这个原理和上一种省略类型信息的声明语法糖一样,短变量声明中的变量类型也是由 Go 编译器自动推导出来的。
- 短变量声明也支持一次声明多个变量,而且形式更为简洁:
a, b, c := 12, 'A', "hello"
。
- 省略类型信息的声明
- Go 语言的变量可以分为两类:一类称为包级变量 (package varible),也就是在包级别可见的变量。如果是导出变量(大写字母开头),那么这个包级变量也可以被视为全局变量;另一类则是局部变量 (local varible),也就是 Go 函数或方法体内声明的变量,仅在函数或方法体内可见。
包级变量的声明形式
- 包级变量只能使用带有 var 关键字的变量声明形式,不能使用短变量声明形式,但在形式细节上可以有一定灵活度。
- 第一类:声明并同时显式初始化。
- 在 Go 标准库中,对于变量声明的同时进行显式初始化的这类包级变量,实践中多使用省略类型信息的“语法糖”格式。
- 第二类:声明但延迟初始化。
- 对于声明时并不立即显式初始化的包级变量,我们可以使用下面这种通用变量声明形式:
var a int32
。
- 对于声明时并不立即显式初始化的包级变量,我们可以使用下面这种通用变量声明形式:
- 第一类:声明并同时显式初始化。
- Go 语言提供了变量声明块用来把多个的变量声明放在一起,并且在语法上也不会限制放置在 var 块中的声明类型,那我们就应该学会充分利用 var 变量声明块,让我们变量声明更规整,更具可读性。
- 通常,我们会将同一类的变量声明放在一个 var 变量声明块中,不同类的声明放在不同的 var 声明块中。
- 变量声明最佳实践中还有一条:就近原则。也就是说我们尽可能在靠近第一次使用变量的位置声明这个变量。就近原则实际上也是对变量的作用域最小化的一种实现手段。
局部变量的声明形式
- 和包级变量相比,局部变量又多了一种短变量声明形式,这是局部变量特有的一种变量声明形式,也是局部变量采用最多的一种声明形式。
- 第一类:对于延迟初始化的局部变量声明,我们采用通用的变量声明形式。
- 第二类:对于声明且显式初始化的局部变量,建议使用短变量声明形式。
- 尽量在分支控制时使用短变量声明形式。