Go语言中的常量
今天记录点的轻松的内容,常量。常量在在一门语言中算是比较简单的内容。但是go语言在常量设计上有一些创新,还挺有趣的。
- 支持无类型常量
- 支持隐式类型转换
- 可用于实现枚举
Go语言引入const关键字来声明变量。
不像java,没有常量的关键字。但是java有enum定义枚举,go没有枚举类型的关键字,通过常量来实现。
无类型常量
首先定义常量和用var声明变量的语法是一样的。
可以显式指定类型,如
1 | const a int = 100 |
要注意,go是强类型语言。即使底层类型一致,不同类型也不可以直接进行运算。必须进行显式的类型转换。如:
1 | type myInt int |
但是如果定义常量的时候不指定类型,就是无类型常量
1 | type myInt int |
这时候用到无类型常量的另一个特性:隐式类型转换
隐式类型转换
无类型常量也不是说就真的没有类型,它也有自己的默认类型,不过它的默认类型 是根据它的初值形式来决定的。像上面代码中的常量 n 的初值为整数形式,所以它的默认 类型为 int。
这样还是有问题的,int和myInt类型的数据不可以直接进行运算。
所以对于无类型常量参与的表达式求值,Go 编译器会根据上下文中的类型 信息,把无类型常量自动转换为相应的类型后,再参与求值计算。也就是会把n转换为myInt类型。
实现枚举
Go没有原生提供枚举类型。枚举类型 本质上就是一个由有限数量常量所构成的集合,所以用const实现枚举并没有什么问题。
1 | // 枚举 |
和常量定义并没有什么区别。
通常这里应该介绍下iota了,但说实话,我并不喜欢iota。
iota称为行偏移量指 示器。
go的枚举有一个特性是自动重复上一行,比如
1 | const ( |
那么TUESDAY和WEDNESDAY的值就都是1
这种情况下可以使用iota
1 | const ( |
在每一个const块中,iota的初始值是0,并且每一行代码的iota的值依次递增。所以上述代码等价于
1 | const ( |
如果想跳过某个iota值,可以使用_
1 | const ( |
再注意一点,iota是每一行的值依次递增,也就是说于同一行的 iota 即便出现多次,多个 iota 的值也是一样的
1 | const ( |
iota看起来挺灵活的,并且在go标准库或者很多知名的开源项目中都有使用。但是在我们平时的开发中还是习惯将常量明确的显式的定义出来。因为常量可读性我认为是更加重要的。我可不想看到这个常量定义,再去算算这个常量到底是多少。
还要注意,在已确定的常量定义中插入一行,会导致下面所有常量的值改变。
比如:
1 | const ( |
和java的enum相比,表现力还是差了很多。