gopl-zh.github.com/ch3/ch3-06-1.md

76 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

### 3.6.1. iota 常量生成器
常量聲明可以使用iota常量生成器初始化它用於生成一組以相似規則初始化的常量但是不用每行都寫一遍初始化表達式。在一個const聲明語句中在第一個聲明的常量所在的行iota將會被置爲0然後在每一個有常量聲明的行加一。
下面是來自time包的例子它首先定義了一個Weekday命名類型然後爲一週的每天定義了一個常量從週日0開始。在其它編程語言中這種類型一般被稱爲枚舉類型。
```Go
type Weekday int
const (
Sunday Weekday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
```
週一將對應0週一爲1如此等等。
我們也可以在複雜的常量表達式中使用iota下面是來自net包的例子用於給一個無符號整數的最低5bit的每個bit指定一個名字
```Go
type Flags uint
const (
FlagUp Flags = 1 << iota // is up
FlagBroadcast // supports broadcast access capability
FlagLoopback // is a loopback interface
FlagPointToPoint // belongs to a point-to-point link
FlagMulticast // supports multicast access capability
)
```
隨着iota的遞增每個常量對應表達式1 << iota,是連續的2的冪,分别對應一個bit位置。使用這些常量可以用於測試、設置或清除對應的bit位的值:
<u><i>gopl.io/ch3/netflag</i></u>
```Go
func IsUp(v Flags) bool { return v&FlagUp == FlagUp }
func TurnDown(v *Flags) { *v &^= FlagUp }
func SetBroadcast(v *Flags) { *v |= FlagBroadcast }
func IsCast(v Flags) bool { return v&(FlagBroadcast|FlagMulticast) != 0 }
unc main() {
var v Flags = FlagMulticast | FlagUp
fmt.Printf("%b %t\n", v, IsUp(v)) // "10001 true"
TurnDown(&v)
fmt.Printf("%b %t\n", v, IsUp(v)) // "10000 false"
SetBroadcast(&v)
fmt.Printf("%b %t\n", v, IsUp(v)) // "10010 false"
fmt.Printf("%b %t\n", v, IsCast(v)) // "10010 true"
}
```
下面是一個更複雜的例子每個常量都是1024的冪
```Go
const (
_ = 1 << (10 * iota)
KiB // 1024
MiB // 1048576
GiB // 1073741824
TiB // 1099511627776 (exceeds 1 << 32)
PiB // 1125899906842624
EiB // 1152921504606846976
ZiB // 1180591620717411303424 (exceeds 1 << 64)
YiB // 1208925819614629174706176
)
```
不過iota常量生成規則也有其局限性。例如它併不能用於産生1000的冪KB、MB等因爲Go語言併沒有計算冪的運算符。
**練習 3.13** 編寫KB、MB的常量聲明然後擴展到YB。