目录 [−]
本文介绍Go语言的常量和变量的语言细节。
常量
只有数值类型和字符串类型才可以作为常量。
数值类型包括 布尔类型、rune类型、各种整型、浮点类型、复数。
常量值既可以是数值类型的字面量,也可以是字符串字面量,以及常量的等价形式, 如:
- 常量表达式, 如
4 * 5
- 转换结果是常量, 如
int(10.0)
- 内建函数的返回值, 如
unsafe.Sizeof
、cap
、len
- 复数、实数和虚数的应用
true
和false
赋值给bool类型的常量- 内建的
iota
用变量赋值给常量是不允许的:
|
|
常量的命名还是遵循前一篇文章的介绍,所有你看到一些"奇怪"的常量名不要觉得奇怪:
|
|
常量可以不声明类型(untyped), 它会根据常量值设置默认的类型,默认类型为:
- bool
- rune
- int
- float64
- complex128
- string
在需要类型的上下文中,常量可以隐式转换成相应的类型:
|
|
注意不同类型的变量是不能转换的:
|
|
你不能将一个不能隐式转换成常量类型的值赋值给常量,比如下面的例子中2147483648.0
不能赋值给int32, 溢出了:
|
|
Go对常量的底层实现有限制:
- Represent integer constants with at least 256 bits.
- Represent floating-point constants, including the parts of a complex constant, with a mantissa of at least 256 bits and a signed exponent of at least 32 bits.
- Give an error if unable to represent an integer constant precisely.
- Give an error if unable to represent a floating-point or complex constant due to overflow.
- Round to the nearest representable constant if unable to represent a floating-point or complex constant due to limits on precision.
声明多个变量的时候可以将声明放在一起:
|
|
或者将多个常量的定义放在一行中:
|
|
常量也可以定义在函数中:
|
|
变量
变量代表一个值的存储位置,每个值都有类型。
变量在声明的时候如果同时有赋值操作,那么类型可以省略,因为可以根据值推断出来:
|
|
类似于常量定义,你可以同时声明多个变量:
|
|
或者一行声明多个变量:
|
|
在上面的例子中i8、i9、i10都是 int类型,所以将类型写在最后面,下面的写法是不允许的:
|
|
下面的语句也是非法的,因为声明的变量和赋值列表的数值数量必须一样:
|
|
变量声明简化
如果变量在声明的时候同时初始化,那么它就可以简化。
比如
|
|
可以简化为
|
|
记住,这个简写方法只能用在函数中,函数之外的变量声明不能简写,下面的写法是错误的。
|
|
不像普通的变量声明,简写方式声明的变量可以"重新声明"已有变量,只要保证有一个新的变量在变量列表中即可,当然“重新声明”的变量和原有变量的类型相同。
看下面的例子就容易理解了:
|
|
这个例子中f
变量重新被声明了,程序正常编译,没有错误,这是因为err
是新的变量。
下面这个例子就编译不过,因为第4行没有新的变量定义。
|
|
不能用简写方法赋值给一个结构体的字段(field):
|
|
注意,简写方法有时候会迷惑你,因为它可能shadow
一个变量,而且正常编译通过:
|
|
在上面的例子中,如果本意是通过一个方法修改变量x的值为200的话,最终打印结果可能是100,因为第三行实际是声明了一个新的变量。
你可以通过vet
工具检查代码中是否包含shadow
的代码:
|
|
输出结果为:
|
|
变量和常量都可以定义在函数内或者包下,但是如果函数内的变量没有被使用,则会编译出错,这是Go语言有意这样设计的。包下的变量和常量,函数内的常量没有这个限制。
参考
* http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang/index.html#short_vars
静态类型和动态类型
静态类型(static type)是变量声明的时候的声明类型,在变量声明、new方法创建对象时或者结构体(struct)的元素的类型定义,参数类型等。
接口(interface)类型的变量还有一个动态类型,它是运行时赋值给这个变量的具体的值的类型(当然值为nil的时候没有动态类型)。一个变量的动态类型在运行时可能改变,
这主要依赖它的赋值。
|
|