【问题标题】:Size of arrays in MemoryLayout.size in SwiftSwift 中 MemoryLayout.size 中数组的大小
【发布时间】:2023-03-09 20:23:01
【问题描述】:

对不起,如果问题可能重复,我在这里找不到,也无法使用谷歌。

我是不安全的 Swift 新手,我想知道为什么布尔数组的大小(例如 10 个字节)仍然是 8 个字节?

如果我不能说出我的意思,我想知道你是否可以看看这段代码:

var boolArray = [Bool]()
for _ in 1...10{
    boolArray.append(true)
}
print(MemoryLayout.size(ofValue: boolArray))

我不明白为什么它打印 8 而数组有 10 个至少包含 10 个字节的布尔值。

【问题讨论】:

  • 无关但有用:您可以将数组生成缩短为 Array(repeating: true, count: 10) 或者如果您正在处理类并想要 10 个不同的对象:(1...10).map { _ in YourClass() }
  • @LeoDabus 你是最好的一种权利 - 技术上正确
  • @ParsaNoori 从技术上讲,您甚至不能在现代 CPU 上加载比缓存行少的任何东西。但是您仍然可以访问成分。虽然您不能单独加载单个位,但您可以加载整个字节,屏蔽除您要查找的位之外的所有位,然后读取它。
  • @ParsaNoori 由于每个字节有 8 位,您可以使用索引的最后 3 位以外的所有位来选择要查看的字节,并使用最后 3 位来编码你感兴趣的位。例如,如果您想要索引 59 处的Bool(二进制中的0b111011),则查看第 7 个字节(0b111)。假设那个字节的值是0b11111111(全是“真”)。我们关心位 3 (0b011),所以我们通过与掩码 0b00000100 进行与运算来掩码 0b1111111。结果是0b00000100,表示设置了第3位。
  • @ParsaNoori 如果该字节的值为0b11111011,在用0b00000100 屏蔽后,我们将得到0x00000000,这意味着第3 位已关闭。

标签: arrays swift unsafe memory-layout


【解决方案1】:

这是因为 Array 本身并不真正存储任何东西 - 在内部,它们持有对堆分配内存的引用,它真正存储数据。

这样做的原因之一是优化 - 它允许使用写时复制机制。 Arraystruct,因此它是一个值类型。但是,不需要每次复制Array时都复制它所保存的数据——相反,多个Arrays可以指向同一个内存区域,只要它们不修改即可。

【讨论】:

  • 有理由猜测代表“Array容器”的数据结构是 8 个字节长。这是一个只对语言设计者感兴趣的不透明结构。
  • @MikeRobinson 相反,它的内部工作令人着迷,并且可能会引起许多从未接触过语言设计的人(包括我自己)的极大兴趣。
【解决方案2】:

因为函数大小的结果不包括任何动态分配或离线存储。见https://developer.apple.com/documentation/swift/memorylayout/2486283-size

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    • 1970-01-01
    • 2021-04-02
    • 1970-01-01
    相关资源
    最近更新 更多