使用以下代码片段

use std::mem;

fn main() {
   println!("size Option(bool): {} ({})", mem::size_of::<Option<bool>>(), mem::size_of::<bool>());
   println!("size Option(u8): {} ({})", mem::size_of::<Option<u8>>(), mem::size_of::<u8>());
   println!("size Option(u16): {} ({})", mem::size_of::<Option<u16>>(), mem::size_of::<u16>());
   println!("size Option(u32): {} ({})", mem::size_of::<Option<u32>>(), mem::size_of::<u32>());
   println!("size Option(u64): {} ({})", mem::size_of::<Option<u64>>(), mem::size_of::<u64>());
   println!("size Option(u128): {} ({})", mem::size_of::<Option<u128>>(), mem::size_of::<u128>())
}

我在我的64位计算机上看到:

size Option(bool): 1 (1)
size Option(u8): 2 (1)
size Option(u16): 4 (2)
size Option(u32): 8 (4)
size Option(u64): 16 (8)
size Option(u128): 24 (16)

因此开销不是恒定的,最高可达8个字节.我想知道为什么开销不是只有一个字节来存储标签?我也想知道编译器 Select 了什么表示法?

推荐答案

关于type layouts的铁 rust 参考在这里开始发挥作用:

[.]值的大小始终是其对齐方式的倍数.[.]

[默认]表示所提供的唯一数据布局保证是可靠所必需的.它们是:[...]

  1. 类型的对齐方式至少是其字段的最大对齐方式.

因此,必须将大小Option<T>向上舍入到最接近的T对齐,即使只使用一个字节(或甚至一个位)来存储"值存在"的信息.

例外情况是允许"null pointer optimization"的类型,其中Option<T>具有与T相同的大小,因为它可以通过使用无效状态T之一来表示None.例如,bool只有两个状态,因此编译器将优化并使用剩余的254个1字节状态中的一个来表示Option<bool>None.这适用于bool&U&mut UfnBox<U>NonZero*NonNull<U>.

Rust相关问答推荐

在rust中如何修改一个盒装函数并将其赋回?

为什么我不能从带有字符串的 struct 的引用迭代器中收集VEC<;&;str&>?

亚性状上位性状上的 rust 病伴生型界限

如何正确重新排列代码以绕过铁 rust 借入判断器?

信号量释放后 Rust 输出挂起线程

使用占位符获取用户输入

Rust 1.70 中未找到 Trait 实现

在Rust中实现Trie数据 struct 的更好方式

在1.5n次比较中找到整数向量中的最大和次大整数

trait 对象指针的生命周期

为什么需要同时为值和引用实现`From`?方法不应该自动解引用或borrow 吗?(2023-06-16)

Rust 中的 Option as_ref 和 as_deref 有什么不同

由特征键控的不同 struct 的集合

我什么时候应该使用特征作为 Rust 的类型?

如何获取函数中borrow 的切片的第一部分?

如何将参数传递给Rust 的线程?

仅在运行测试时生成调试输出

只有一个字符被读入作为词法分析器的输入

为什么基于 clap::Parser 读取的大量数字进行计算比硬编码该数字时慢?

类型参数不受 impl 特征、自身类型或谓词的约束