typora/note/Go/常量.md

118 lines
2.6 KiB
Markdown
Raw Normal View History

2024-12-11 21:48:55 -05:00
### 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 的值也是一样的
- 其值一直自增直到遇到下一个const关键字其值才被重新置为
```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
)
```