直接回答:niche(空位)指一个类型取值集合中的“非法值”——引用的取值集合不包含空地址,NonZero 不包含 0,bool 只有 0 和 1 两个合法位模式。当 Option 的 T 存在空位时,编译器用空位表示 None,判别值就省掉了:size_of::<Option<&T>>() == size_of::<&T>(),都是 8 字节。这让 Option 包装在大量场景下零开销,是 Rust 能把“可空”做成零成本抽象的关键机制。
展开解析:适用范围:Option<&T>、Option<Box>、Option、Option(2 字节变 1 字节)都受益;Result<usize, ErrorType> 这类要看错误类型有无空位。反向情况:Option 没有空位可用,必须额外 1 字节判别值再加对齐填充,共 8 字节。实践意义:写 FFI 时可以安全地把 Option<extern "C" fn(...)>、Option<&T> 映射为可空指针(标准库对部分类型保证此布局);设计内存敏感的数据结构时,用 NonZero 类型可以让 Option 包装免费;自定义类型如果需要这个优化,可以内部包 NonZero。注意该优化是编译器启发式,布局上除非用 repr(C) 或文档明确保证的类型,不应在 unsafe 代码里硬依赖具体布局。相关的还有枚举布局优化与填充字节利用,都是同一思想的延伸。
追问方向:为什么 Option<Option<&T>> 会变大?repr(C) 之后还有这个优化吗?
(约 460 字)