为何Rust中两个枚举类型的size_of结果存在差异?
Rust枚举大小差异的原因分析
先明确64位系统下的基础数据:
size_of::<String>()= 24(由指针、长度、容量三个8字节字段组成)align_of::<String>()= 8(指针类型的对齐要求为8字节)
为什么demo的大小是48字节?
demo包含两个变体:a(String)(24字节)和b(String, String)(48字节)。
Rust在这里用到了空指针优化的扩展逻辑:因为String的指针永远不会是空的(String必须指向有效的内存,不能为null),所以可以用变体的填充空间存储区分标识:
- 当是
a变体时,把后面24字节(对应b变体的第二个String位置)的指针设为null,以此标记这是a; - 当是
b变体时,第二个String的指针必然非null,以此标记这是b。
这种情况下不需要额外的标签字段,整个枚举的大小等于最大变体的大小48字节,同时满足8字节的对齐要求。
为什么新增c(i8)后demo2的大小变成56字节?
新增c(i8)变体后,现在有三个变体,仅靠“第二个String指针是否为null”已经无法区分三个状态了。此时Rust必须引入一个单独的标签字段来标识当前是哪个变体。
虽然标签理论上只需要1字节就能存储3个状态,但由于整个枚举的对齐要求由最大变体b决定(8字节对齐),标签字段也必须对齐到8字节(否则整个枚举的对齐会被拉低,无法满足String的对齐要求)。因此标签占用8字节空间。
最终demo2的大小就是最大变体的48字节加上标签的8字节,总共56字节。
内容的提问来源于stack exchange,提问作者Shivam Varshney
相关产品推荐
相关产品推荐

