Swift 中的神秘枚举
2023-11-05 05:41:43
序幕
枚举是 Swift 中一种非常强大的类型,它可以用来表示一组相关的常量。枚举的成员可以是显式定义的,也可以是隐式分配的。枚举还可以有 RawValue,这是一种可以在枚举成员中存储的原始值。
枚举的种类
隐式分配机制
隐式分配机制是指,当我们没有显式地为枚举成员指定值时,编译器会自动为它们分配值。这种分配机制从 0 开始,并且对于每个后续的枚举成员,其值都会增加 1。例如:
enum CompassPoint {
case north
case south
case east
case west
}
在这个枚举中,north 的值是 0,south 的值是 1,east 的值是 2,west 的值是 3。
RawValue
RawValue 是可以在枚举成员中存储的原始值。RawValue 可以是任何类型,但最常见的是整数、字符串或布尔值。例如:
enum Planet: Int {
case mercury = 1
case venus = 2
case earth = 3
case mars = 4
}
在这个枚举中,mercury 的 RawValue 是 1,venus 的 RawValue 是 2,earth 的 RawValue 是 3,mars 的 RawValue 是 4。
枚举在 SIL 文件中的表示
在 SIL 文件中,枚举的 getter 方法是用来获取枚举值的。例如,对于以下枚举:
enum CompassPoint {
case north
case south
case east
case west
}
其 getter 方法的 SIL 表示如下:
sil hidden [transparent] @$s12CompassPointO5northACvg : $@convention(thin) (@guaranteed CompassPoint) -> Int {
bb0(%0 : $*CompassPoint):
%1 = integer_literal $Builtin.Int64, 0
switch_enum %0 : $CompassPoint, case #CompassPoint.north!enumelt: bb1, case #CompassPoint.south!enumelt: bb2, case #CompassPoint.east!enumelt: bb3, case #CompassPoint.west!enumelt: bb4
bb1:
br bb5(%1 : $Builtin.Int64)
bb2:
%2 = integer_literal $Builtin.Int64, 1
br bb5(%2 : $Builtin.Int64)
bb3:
%3 = integer_literal $Builtin.Int64, 2
br bb5(%3 : $Builtin.Int64)
bb4:
%4 = integer_literal $Builtin.Int64, 3
br bb5(%4 : $Builtin.Int64)
bb5(%5 : $Builtin.Int64):
return %5 : $Builtin.Int64
}
在这个 SIL 代码中,switch_enum 指令用于根据枚举值的类型来跳转到不同的基本块。例如,如果枚举值是 north,则会跳转到 bb1 基本块。在 bb1 基本块中,integer_literal 指令用于创建一个整数字面量 0,然后 br 指令用于返回这个整数字面量。
枚举值的字符串表示
枚举值的字符串表示是在编译的时候就已经构建好的,并且存放在 Macho 文件中。例如,对于以下枚举:
enum CompassPoint {
case north
case south
case east
case west
}
其枚举值的字符串表示如下:
CompassPoint.north = "north"
CompassPoint.south = "south"
CompassPoint.east = "east"
CompassPoint.west = "west"
这些字符串表示存放在 Macho 文件的字符串表中。当我们使用 String(describing:) 函数来获取枚举值的字符串表示时,编译器会从字符串表中查找相应的字符串。
结语
枚举是 Swift 中一种非常强大的类型,它可以用来表示一组相关的常量。枚举可以有隐式分配机制,也可以有 RawValue。在 SIL 文件中,枚举的 getter 方法是用来获取枚举值的。构建枚举值的字符串是在编译的时候就已经构建好的,并且存放在 Macho 文件中。