2.6 KiB
2.6 KiB
Go 常量创新
- 支持无类型常量
- 支持隐式自动转型
- 可用于实现枚举
无类型常量
- 常量声明时没有被显示设置类型
- const n 根据字面值推断类型为int
package main
import (
"fmt"
)
type myInt int
const n = 13
const m int64 = n + 5 // OK
func main() {
var a int = 5
fmt.Println(a + n) // 输出:18
}
隐式转型
- 对于无类型常量参与的表达式求值,Go 编译器会根据上下文中的类型信息,把无类型常量自动转换为相应的类型后,再参与求值计算
- 转型的对象是一个常量,并不会引发类型安全问题,Go 编译器会保证这一转型的安全性
- 如果 Go 编译器在做隐式转型时,发现无法将常量转换为目标类型,Go 编译器也会报错
const m = 1333333333
var k int8 = 1
j := k + m // 编译器报错:constant 1333333333 overflows int8
实现枚举
- Go 的 const 语法提供了“隐式重复前一个非空表达式”的机制
package main
import (
"fmt"
)
const (
Apple = 11
Banana = 12
Strawberry
Pear
)
func main() {
fmt.Println(Apple)
fmt.Println(Pear)
}
iota
const 声明块(包括单行声明)中,每个常量所处位置在块中的偏移值(从零开始)- 每一行中的 iota 自身也是一个无类型常量,可以像无类型常量那样,自动参与到不同类型的求值过程中来,不需要再对它进行显式转型操作
- 同一行的 iota 即便出现多次,多个 iota 的值也是一样的
- 其值一直自增1直到遇到下一个const关键字,其值才被重新置为0
// $GOROOT/src/sync/mutex.go
const (
mutexLocked = 1 << iota // 刚开始iota为1,后续自增1, 1 << 0
mutexWoken // 定义时没有显示赋值,重复上一行的值,1 << iota,相当于1 << 1
mutexStarving // 同上
mutexWaiterShift = iota // 重新设置为3
starvationThresholdNs = 1e6
)
const (
Apple, Banana = iota, iota + 10 // 0, 10 (iota = 0)
Strawberry, Grape // 1, 11 (iota = 1)
Pear, Watermelon // 2, 12 (iota = 2)
)
- 略过iota中的0或者某个值
// $GOROOT/src/syscall/net_js.go
const (
_ = iota
IPV6_V6ONLY // 1
SOMAXCONN // 2
SO_ERROR // 3
)
const (
_ = iota // 0
Pin1
Pin2
Pin3
_
Pin5 // 5
)
- 每个const块都有自己的iota
const (
a = iota + 1 // 1, iota = 0
b // 2, iota = 1
c // 3, iota = 2
)
const (
i = iota << 1 // 0, iota = 0
j // 2, iota = 1
k // 4, iota = 2
)