Swift 枚举字节表示是什么?
What is Swift enum byte representation?
我有以下枚举:
enum Enum: UInt8
{
case A = 0x00
case B = 0x01
case C = 0x10
}
我用下面的代码把它转换成NSData
:
var value = Enum.C
let data = NSData(bytes: &value, length: 1)
当然,我希望data
包含0x10
,然而,它包含0x02
.
对于 Enum.A
,它包含 0x00
,对于 Enum.B
,它包含 0x01
。
对我来说,它看起来像是存储值的索引而不是实际的原始数据。有人可以解释这种行为吗?
P.S。如果我使用 rawValue
它会完美运行。但是,我想了解背后的原因,因为我无法创建通用函数来将值转换为 NSData。
每个枚举案例都有一个标准的顺序值。当你不使用 .rawValue
.
时,你会得到什么
例如,如果您将枚举更改为:
enum Enum: UInt8
{
case A = 0x00
case B = 0x01
case B2 = 0x0A
case C = 0x10
}
然后,当执行
var value = Enum.C
let data = NSData(bytes: &value, length: 1)
data
将是 3
,因为 A = 0
、B = 1
、B2 = 2
、C = 3
Swift ABI 仍在进行中(预计会在 Swift 4 中修复)。枚举在内存中的表示方式 is described here.
您的案例是 "c-like enum" 因为它有...
- 两个或更多案例
- 没有关联值
引用 ABI 文档:
the enum is laid out as an integer tag with the minimal number of bits to contain all of the cases. [...] The cases are assigned tag values in declaration order.
这里的关键信息是"minimal number of bits"。这意味着(对于您的情况)实例应该适合两位(因为您有三种情况)。 rawValue 0x10
需要五位——这会与 ABI 冲突。
编译器可能使用静态表在 Enum
实例和它们的 rawValue
实例之间进行转换(以及返回)。
下面是一个突出 ABI 特性的示例:
enum Enum: UInt32
{
case A = 0
case B = 0xffffffff // value that does not fit into one byte
}
assert(sizeof(Enum.self) == 1)
我有以下枚举:
enum Enum: UInt8
{
case A = 0x00
case B = 0x01
case C = 0x10
}
我用下面的代码把它转换成NSData
:
var value = Enum.C
let data = NSData(bytes: &value, length: 1)
当然,我希望data
包含0x10
,然而,它包含0x02
.
对于 Enum.A
,它包含 0x00
,对于 Enum.B
,它包含 0x01
。
对我来说,它看起来像是存储值的索引而不是实际的原始数据。有人可以解释这种行为吗?
P.S。如果我使用 rawValue
它会完美运行。但是,我想了解背后的原因,因为我无法创建通用函数来将值转换为 NSData。
每个枚举案例都有一个标准的顺序值。当你不使用 .rawValue
.
例如,如果您将枚举更改为:
enum Enum: UInt8
{
case A = 0x00
case B = 0x01
case B2 = 0x0A
case C = 0x10
}
然后,当执行
var value = Enum.C
let data = NSData(bytes: &value, length: 1)
data
将是 3
,因为 A = 0
、B = 1
、B2 = 2
、C = 3
Swift ABI 仍在进行中(预计会在 Swift 4 中修复)。枚举在内存中的表示方式 is described here.
您的案例是 "c-like enum" 因为它有...
- 两个或更多案例
- 没有关联值
引用 ABI 文档:
the enum is laid out as an integer tag with the minimal number of bits to contain all of the cases. [...] The cases are assigned tag values in declaration order.
这里的关键信息是"minimal number of bits"。这意味着(对于您的情况)实例应该适合两位(因为您有三种情况)。 rawValue 0x10
需要五位——这会与 ABI 冲突。
编译器可能使用静态表在 Enum
实例和它们的 rawValue
实例之间进行转换(以及返回)。
下面是一个突出 ABI 特性的示例:
enum Enum: UInt32
{
case A = 0
case B = 0xffffffff // value that does not fit into one byte
}
assert(sizeof(Enum.self) == 1)