属性声明顺序是否会影响Swift结构体的内存布局?
属性声明顺序对Swift结构体的MemoryLayout有影响吗?
答案是肯定的——属性声明顺序确实会影响结构体的size(实际占用的内存大小),不过不一定会改变alignment(内存对齐要求)和stride(内存分配的步长)。咱们结合你给出的例子来拆解:
先看完整的代码输出(补充了size的打印结果):
struct Foo { let myInt: Int let myBool: Bool } struct Bar { let myBool: Bool let myInt: Int } print(MemoryLayout<Foo>.stride) // 16 print(MemoryLayout<Bar>.stride) // 16 print(MemoryLayout<Foo>.alignment) // 8 print(MemoryLayout<Bar>.alignment) // 8 print(MemoryLayout<Foo>.size) // 9 print(MemoryLayout<Bar>.size) // 16
为什么会出现这样的差异?
这得从Swift的内存对齐规则说起:
- 基本数据类型都有固定的对齐要求:64位系统下,
Int需要8字节对齐,Bool只需要1字节对齐。 - 结构体的对齐要求由它内部对齐要求最高的成员决定(这里两个结构体都有
Int,所以alignment都是8)。
先看Foo的内存布局:
- 先存放
myInt:占用前8字节,刚好满足它的对齐要求。 - 接着存放
myBool:占用第9字节。 - 实际总占用内存是9字节(也就是
size=9),但因为结构体要满足8字节的对齐要求,所以内存分配时会按照8的倍数来预留空间,也就是stride=16,剩下的7字节是填充(padding),不被实际数据占用。
再看Bar的内存布局:
- 先存放
myBool:占用第1字节。 - 接下来要放
myInt,但Int必须从8字节的倍数位置开始存放,所以在myBool后面会填充7字节的空白,从第8字节开始存放myInt的8字节。 - 这样实际总占用内存就是1+7+8=16字节(
size=16),刚好是8的倍数,所以stride也是16。
总结一下:
属性声明顺序影响的是内存填充的位置和数量,直接改变了结构体实际占用的内存大小(size)。但如果结构体包含的成员类型完全相同,它的对齐要求(alignment)和分配步长(stride)通常是一致的,因为这两个值主要由内部对齐要求最高的成员决定。
内容的提问来源于stack exchange,提问作者Ahmad F
相关产品推荐
相关产品推荐

