Option 类型是否小于包装类型加上布尔值?

Nar*_*ann 1 struct boolean padding optional rust

use std::mem::size_of;

struct Position {
    x: f32,
    y: f32,
    z: f32,
}

struct PoolItem {
    entity_id: u32, // 4 bytes
    used: bool, // 1 bytes + 3 (padding)
    component: Position, // 12 bytes
}


assert_eq!(size_of::<u32>(), 4);
assert_eq!(size_of::<Position>(), 12);
assert_eq!(size_of::<PoolItem>(), 20);
Run Code Online (Sandbox Code Playgroud)

如您所见,这样的结构有 20 个字节长。Position实际上是可选的并且取决于used.

使用会Option消除对used字段的需求并将结构大小减少到 16 个吗?

struct PoolItem {
    entity_id: u32, // 4 bytes
    component: Option<Position>, // 12 bytes ?
}
Run Code Online (Sandbox Code Playgroud)

如果是这样,如何Option实现这种行为?

我在Playground 上的测试似乎表明它不起作用。为什么?

Sha*_*ger 5

的精确实施Option并不重要。什么是显而易见的是,你不能存储X的数据量X的存储量,并还可以存储数据是否是那里。一个明显的实现Option是同时存储对象和指示对象是否存在的布尔值;显然,类似的事情正在发生。Option为了方便,它仍然需要将信息存储在某个地方。

请注意,如果优化器struct始终Option确定Option已知的“已填充或未填充”状态,则在a 之外(必须具有一致的大小)可能会避免此成本,因此可能会忽略布尔值以支持始终在以下情况下确定性地使用它的代码正确的方法(如果逻辑上存在,则从堆栈中读取对象,或者在不存在时不这样做)。但在这种情况下,需要额外的数据。

  • 没有指针。`Position` 的 12 个字节直接嵌入到父结构中。 (4认同)
  • @CoronA值得注意的是,如果您确实将“Position”放在不可空指针后面,例如“Box&lt;Position&gt;”、“&amp;Position”或“Rc&lt;Position&gt;”,编译器实际上会将其编码为你建议。“零成本抽象”是一个通用术语,通常在将内置抽象(如“Option&lt;T&gt;”)与修辞性的手动编码等效项(如包含“T”和布尔标志的结构)进行比较时应用。从这个意义上说, Option&lt;T&gt; 确实是零成本的,因为即使该标志是必要的,也不可能更好地对其进行手动编码。 (2认同)