118 lines
2.6 KiB
Markdown
118 lines
2.6 KiB
Markdown
### Go 常量创新
|
||
- 支持无类型常量
|
||
- 支持隐式自动转型
|
||
- 可用于实现枚举
|
||
|
||
### 无类型常量
|
||
- 常量声明时没有被显示设置类型
|
||
- const n 根据字面值推断类型为int
|
||
```go
|
||
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 编译器也会报错
|
||
```go
|
||
|
||
const m = 1333333333
|
||
|
||
var k int8 = 1
|
||
j := k + m // 编译器报错:constant 1333333333 overflows int8
|
||
```
|
||
|
||
### 实现枚举
|
||
- Go 的 const 语法提供了“隐式重复前一个非空表达式”的机制
|
||
```go
|
||
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
|
||
```go
|
||
|
||
// $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或者某个值
|
||
```go
|
||
|
||
// $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
|
||
```go
|
||
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
|
||
)
|
||
``` |