常量
什么是字面量
考虑下面代码:
这里变量a
赋值为字面量50
,变量b
赋值为字面量I love Go
,而变量c
则赋值为变量b
。像5
, -89
,I love Go
,67.89
等,在编程语言中称为字面量。
什么是常量
常量是相对于变量而言的,考虑下面代码:
这里两个量a
和b
虽然都是声明为int
类型,并且赋值为50,但是a
是变量,b
是常量。那么常量与变量有什么区别呢?答案是常量不可重新被赋值。
Go Playground在线运行 这里由于a
被声明为了const
常量,因此后面再进行赋值会报错。
常量跟变量的另外一个不同点是,常量声明的同时需要赋值,因此下面的写法会报错:
另外需要注意,常量值需要在编译时确定,因此不能将函数调用的返回值赋值给常量。
该程序中,a
是变量,因此可以赋值为函数调用返回值;但是b
是常量,而函数math.Sqrt(4)
的执行是运行时,因此会报错。
无类型常量和有类型常量
Golang中每个变量都有对应的类型,比如:
这三种不同的写法,声明的变量a
、b
、c
均为int
类型,虽然有显示声明的,有Golang自动推断的,有简写形式。
Golang中的常量与变量不同,常量包括两种:untyped常量(无类型常量)和typed常量(有类型常量)。为了方便理解,这里以香水为例来说明下。我们都知道,兰蔻(Lancome)和欧碧泉(Biotherm)都属于欧莱雅集团,假如他们公司新发明了一款香水:邂逅
。
Go Playground在线运行 这段程序中,首先声明的常量perfume
就是无类型常量,而后面声明的perfume1
和perfume2
则均是有类型常量,其常量类型分别是Lancome
和Biotherm
。虽然都是常量,但是用法却不同,后面声明的变量perfume3
是Lancome
类型,因此只能赋值为同类型常量perfume1
或者无类型常量perfume
。
为了加深理解我们继续深挖香水这个例子。虽然邂逅
这款香水是欧莱雅集团出品的,但是在贴标之前是没有品牌属性的,即const perfume = "邂逅"
,这行代码我们 并未给perfume
常量贴标,因此不属于任何品牌,属于无类型常量。但是一旦贴标,比如const perfume2 Biotherm = "邂逅"
,这行代码我们给perfume2
常量贴标,贴上Biotherm品牌标志,即变为有类型常量。有类型常量是贴标产品,因此不能随便再撕下标签,贴上其他品牌的标志,比如perfume3 = perfume2
,因此这行代码是不合法的。
初看这个特性难以理解,但是这样使得Golang的常量更加灵活,我们首先声明无类型的常量,后面用起来就会更加灵活,只要类型兼容,想赋值给什么变量就赋值给什么变量。这里再解释下这里所说的类型兼容,比如const str = "邂逅"
中无类型常量str
本质是一个字符串,与类型string
、Lancome
均兼容,这里的类型兼容用来描述无类型常量与其他类型的兼容性:
字符串常量
字符串常量声明如下:
参考前面对无类型常量和有类型常量的解释,这里声明了一个无类型字符串常量hello
。 看下下面的代码你可能会疑惑,为什么说hello
是无类型的呢,明明打印出了string
。
运行结果如下:
这里解释下。前面之所以打印出了string
,并不是说常量name
是Golang的string
类型。本质原因是因为这里name
是作为了fmt.Printf
函数的参数,而该函数这里期望接收string
类型,又因为常量"Sam"本身是一个字符串,与string
类型兼容,因此才打印出了string
。
布尔常量
布尔常量没什么特殊的,很简答,这里仅举个例子:
Go Playground在线运行 这里由于变量defaultBool
是布尔类型,因此可被赋值无类型常量tureConst
,但是不能被赋值为类型不相同的有类型常量customBool
。
数值常量
数值常量包括整型、浮点型以及复数型。
Go Playground在线运行 这里常量a
是无类型的,值为5
,由于是无类型的,因此可以赋值为多种兼容的类型,执行结果如下:
从下面的程序我们可以看出整型变量、浮点型变量以及复数型变量被赋值常量时的默认类型分别是int
,float64
,complex128
:
Go Playground在线运行 执行结果如下:
数值表达式
数值型常量声明时也不可以使用函数调用返回值来初始化,但是可以使用数值表达式来初始化,比如:
执行结果如下:
Last updated
Was this helpful?