一、常量的概念
常量,就是在程序编译阶段就确定下来而程序在运行时则无法改变的值。一般存放在内存的数据区。常量的潜在类型都是基础类型:布尔值、字符串或者数值类型(包括整型、浮点型和复数类型)。常量比变量更适合用于表达像π之类的数学常数,因为它们的值不会发生变化。相对于C/C++中const不同的是,Go中的constant只是一个简单的,不可修改的值。
二、“定义”常量
在Go语言中,我们用 const 关键字来声明常量。可以单个声明,也可以批量声明。方式如下:
//const constantName [type]= value
const pi = 3.1415926535897932384626
const (
e = 2.7182818284590452353602
pi = 3.1415926535897932384626
)
Go的常量定义可以限定常量类型,但不是必需的。如果定义常量时没有指定类型,那么它是无类型常量。如上面的pi就是无类型浮点常量,是根据右面表达式的类型进行推断的。可以通过%T参数打印类型信息。比如上面的pi通过%T得到的类型就是float64。
const noDelay time.Duration = 0
const timeout = 5 * time.Minute
fmt.Printf("%T %[1]v\n", noDelay) // "time.Duration 0"
fmt.Printf("%T %[1]v\n", timeout) // "time.Duration 5m0s"
fmt.Printf("%T %[1]v\n", time.Minute) // "time.Duration 1m0s"
所有常量的运算都在编译期完成,这样可以减少运行时的工作,也方便其他编译优化。且一些运行时的错误可以在编译时发现。常量间的所有算术运算、逻辑运算和比较运算的结果也是常量。所以,右值也可以是一个在编译期运算的常量表达式。如 1<<3。
三、 iota 常量生成器
Go语言预定义了这些常量: true、 false和iota。 其中iota是咱们特殊需要理解的。iota常量生成器用于生成一组以相似规则初始化的常量,而不用每行都写一遍初始化表达式。 它默认开始值是0,每调用一次加1。遇到 const 关键字时被重置为 0。
const (
c0 = iota // c0 == 0
c1 // c1 == 1
c2 // c2 == 2
)
//<< 左移n位就是乘以2的n次方。
const (
a = 1 << iota // a == 1 (iota在每个const开头被重设为0)
b // b == 2
c // c == 4
)
在其它编程语言中,这种类型(一系列相关的常量)一般被称为枚举类型。Go语言并不支持众多其他语言明确支持的enum关键字。在 const 后跟一对圆括号的方式定义一组常量,这种定义法在Go语言中通常用于定义枚举值。
const (
Sunday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
numberOfDays
)
四、 无类型常量
Go语言的常量有个不同寻常之处。许多常量并没有一个明确的基础类型。编译器为这些没有明确基础类型的数字常量提供比基础类型更高精度的算术运算。主要有六种未明确类型的常量类型:
- 无类型的布尔型
- 无类型的整数
- 无类型的字符
- 无类型的浮点数
- 无类型的复数
- 无类型的字符串
通过延迟明确常量的具体类型,无类型的常量不仅可以提供更高的运算精度,而且可以直接用于更多的表达式而不需要显式的类型转换。例如,math.Pi无类型的浮点数常量,可以直接用于任意需要浮点数或复数的地方:
var x float32 = math.Pi
var y float64 = math.Pi
var z complex128 = math.Pi
只有常量可以是无类型的。当一个无类型的常量被赋值给一个变量的时候,或者出现在有明确类型的变量声明的右边,无类型的常量将会被隐式转换为对应的类型(如果转换合法的话)。
var f float64 = 3 + 0i // untyped complex -> float64
f = 2 // untyped integer -> float64
f = 1e123 // untyped floating-point -> float64
f = 'a' // untyped rune -> float64
好了,关于常量相关的知识点就总结到这里,接下来可以继续了解 类型断言。