枚举iota的示例
Iota 基本示例
iota 关键字表示连续的整数常量 0、1、2,…
每当单词出现在源代码中时,它就会重置为 0,const并在每个 const 规范之后递增。
本文将介绍几种不同的 iota 使用方式,以及有关在何处谨慎使用它的提示。
const (
C0 = iota
C1 = iota
C2 = iota
)
fmt.Println(C0, C1, C2) // "0 1 2"
这可以简化为
const (
C0 = iota
C1
C2
)
在这里,我们依赖于表达式隐式重复的事实 在带括号的 const 声明中 – 这表示重复 的表达式及其类型。
2 从一个开始
要从 1 而不是 0 开始常量列表,可以在算术表达式中使用。iota
const (
C1 = iota + 1
C2
C3
)
fmt.Println(C1, C2, C3) // "1 2 3"
3 跳过值
您可以使用空白标识符跳过常量列表中的值。
const (
C1 = iota + 1
_
C3
C4
)
fmt.Println(C1, C3, C4) // "1 3 4"
使用字符串完成枚举类型 ,以下是实现枚举类型的惯用方法:
创建一个新的整数类型,使用 列出其值 ,iota为类型String指定一个函数。
type Direction int
const (
North Direction = iota
East
South
West
)
func (d Direction) String() string {
return [...]string{"North", "East", "South", "West"}[d]
}
使用:
var d Direction = North
fmt.Print(d)
switch d {
case North:
fmt.Println(" goes up.")
case South:
fmt.Println(" goes down.")
default:
fmt.Println(" stays put.")
}
// Output: North goes up.
命名约定
标准命名约定是对常量也使用混合大写字母。 例如,导出的是常量 , 而不是 North West NORTH_WEST
4 完整形式
const (
a = iota // 0
b = iota // 1
c = iota // 2
)
func main() {
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
}
-
省略形式
const ( a = iota // 0 b // 1 c // 2 ) func main() { fmt.Println(a, b, c) }
-
顺序
忽略0
const (
_ = iota // 0
b = iota * 10 // 1 * 10
c = iota * 10 // 2 * 10
)
func main() {
fmt.Println(b,c)
//fmt.Println(c)
}
5 多段定义
const (
a = iota // 0
b // 1
c // 2
)
const (
d = iota // 0
e // 1
f // 2
)
字节大小容量
const (
a_ = iota // ignore first value by assigning to blank identifier
KB ByteSize = 1 << (10 * iota)
MB
GB
TB
PB
EB
ZB
YB
)
func main() {
fmt.Println(a, b, c, d, e, f)
//fmt.Println(b)
//fmt.Println(c)
//fmt.Println(d)
//fmt.Println(e)
//fmt.Println(f)
fmt.Println(a_, KB, MB, GB, TB, PB, EB, ZB, YB)
}
Iota 是在 Go 中创建递增常量的有用概念。但是,iota 可能不适合在几个领域使用。
6 字节大小的示例
通过位移位数方便地表示字节大小。
const (
read = 1 << iota // 00000001 = 1
write // 00000010 = 2
remove // 00000100 = 4
// admin will have all of the permissions
admin = read | write | remove
)
func main() {
fmt.Printf("read = %v\n", read)
fmt.Printf("write = %v\n", write)
fmt.Printf("remove = %v\n", remove)
fmt.Printf("admin = %v\n", admin)
}
这样,我们可以看到我们打印出了位掩码值:
$ go run main.go
read = 1
write = 2
remove = 4
admin = 7
更进一步,使用它来计算内存大小等内容。例如,让我们看看以下一组常量:
const (
KB = 1024 // binary 00000000000000000000010000000000
MB = 1048576 // binary 00000000000100000000000000000000
GB = 1073741824 // binary 01000000000000000000000000000000
)
这可以通过使用 shift 运算符和乘数来重写iota
const (
_ = 1 << (iota * 10) // ignore the first value
KB // decimal: 1024 -> binary 00000000000000000000010000000000
MB // decimal: 1048576 -> binary 00000000000100000000000000000000
GB // decimal: 1073741824 -> binary 01000000000000000000000000000000
)
这将产生以下值:
KB = 1024
MB = 1048576
GB = 1073741824
完整形式
const (
_ = iota // 0
KB = 1 << (iota * 10) // 1 << (1 * 10)
MB = 1 << (iota * 10) // 1 << (2 * 10)
GB = 1 << (iota * 10) // 1 << (3 * 10)
TB = 1 << (iota * 10) // 1 << (4 * 10)
)
func main() {
fmt.Println("binary\t\tdecimal")
fmt.Printf("%b\t", KB)
fmt.Printf("%d\n", KB)
fmt.Printf("%b\t", MB)
fmt.Printf("%d\n", MB)
fmt.Printf("%b\t", GB)
fmt.Printf("%d\n", GB)
fmt.Printf("%b\t", TB)
fmt.Printf("%d\n", TB)
}
7 在令牌包使用iota
一个领域是 Go 中的令牌包。他们使用了几个聪明技巧来验证常量。
例如,我们可以看到它们使用几个标识符来表示一组常量值的。
literal_beg
// Identifiers and basic type literals
// (these tokens stand for classes of literals)
IDENT // main
INT // 12345
FLOAT // 123.45
IMAG // 123.45i
CHAR // 'a'
STRING // "abc"
literal_end
有一个函数来验证该范围内的任何值:
func (tok Token) IsLiteral() bool { return literal_beg < tok && tok < literal_end }
这些值都不会导出,因此无需担心常量值的未来变化。
- 点赞
- 收藏
- 关注作者
评论(0)