
2.2 var与:=
作为一门精巧的编程语言,Go提供了多种声明变量的方法。究其原因:每种变量声明的风格都明确地传达出使用变量的意图。接下来我们一一介绍变量声明的方法。
最冗长的方式是使用var
关键字,紧跟显式的标注类型,然后赋值,代码如下:

如果=
右侧是变量的预期类型,那么可以省略=
左侧的类型。因为整数字面量的默认类型是整型,故以下声明的变量x
是整型:

如果声明了一个变量,但是没有对其赋值,即没有=
及右边的部分,则变量的值是零值:

当有多个类型相同的变量需要声明时,可以使用:

声明多个零值变量,可以使用:

如果多个变量的类型不一致,可以使用上面介绍的省略类型的方式:

使用关键字var一次声明多个变量时,可以用如下形式:

Go还支持短声明格式,即使用赋值运算符:=
代替var
的形式。以下两行代码都声明一个值为10的整型变量x
:

与var
一样,:=
也可以一次性声明多个变量,下面两行代码都是将10赋值给x
,将“hello”赋值给y
:

:=
运算符还有使用var
关键字无法完成的功能:它允许对已经赋值的变量再次赋值,只要:=
左边有任意一个新变量即可:

短声明格式只能用来声明在函数内部的局部变量,如果在包级别声明变量,只能使用var
关键字,:=
是不合法的。
面对如此众多的声明方式,如何选择呢?只需要选择最能表达意图、最有可读性的方式即可。通常,在函数内部选择使用:=
的短声明格式;在函数外,包级别使用var
的多变量声明格式。
以下几种情况在函数内请避免使用:=
:
- 当需要初始化一个变量为零值时,使用
var x int
,这清晰地表达了零值的意图。 - 当需要将无类型常量或者字面量赋值给一个变量时,如果常量或者字面量的默认类型不是变量的预期类型,需要使用
var
标准形式声明变量。尽管可以使用:=
的方式进行类型转换,例如x:= byte(20)
,但是建议使用Go语言的惯用方法var x byte =20
。 - 因为
:=
既可以赋值给新变量也可以赋值给现有的变量,所以会导致当你认为在重用现有变量时,却在创建变量(详见4.1.1节)。为避免这样存在歧义的方式,建议显式地使用var
关键字声明所有新的变量,然后用赋值运算符=
为新旧变量进行赋值。
Go支持函数的多返回值和“逗号和ok”(见3.4.2节)的语法,当同时声明多个变量时,我们需要使用var
或:=
的方式。
要谨慎在函数外的包代码块(pakcage block)(见4.1节)内声明变量。当一个变量在函数外时,意味着它可能有太多被修改的途径,理解和追踪这些途径太困难,会导致一些不易察觉的bug。所以包代码块中声明的变量应该是不可变的。
避免在函数外声明变量,否则会导致数据流分析变得复杂。
既然需要声明的变量是不可变的,那么在Go中是否有这样的方式呢?回答是当然有,它就是我们接下来要介绍的常量const
。