在防锈,引用不能为空,所以在情况下,你确实需要空,比如一个链表,使用Option
类型:
struct Element {
value: i32,
next: Option<Box<Element>>,
}
多少开销参与这个内存分配和步骤取消引用的条款相比,一个简单的指针? 有一些“神奇”的编译器/运行时做出Option
无成本,或者成本小于如果一个人实现Option
使用相同的非核心库自行enum
结构,或通过在载体包裹指针?
在防锈,引用不能为空,所以在情况下,你确实需要空,比如一个链表,使用Option
类型:
struct Element {
value: i32,
next: Option<Box<Element>>,
}
多少开销参与这个内存分配和步骤取消引用的条款相比,一个简单的指针? 有一些“神奇”的编译器/运行时做出Option
无成本,或者成本小于如果一个人实现Option
使用相同的非核心库自行enum
结构,或通过在载体包裹指针?
是的,有优化一些编译器魔术Option<ptr>
到单个指针(大部分时间)。
use std::mem::size_of;
macro_rules! show_size {
(header) => (
println!("{:<22} {:>4} {}", "Type", "T", "Option<T>");
);
($t:ty) => (
println!("{:<22} {:4} {:4}", stringify!($t), size_of::<$t>(), size_of::<Option<$t>>())
)
}
fn main() {
show_size!(header);
show_size!(i32);
show_size!(&i32);
show_size!(Box<i32>);
show_size!(&[i32]);
show_size!(Vec<i32>);
show_size!(Result<(), Box<i32>>);
}
以下尺寸被打印(64位机器上,所以指针是8个字节):
// As of Rust 1.22.1
Type T Option<T>
i32 4 8
&i32 8 8
Box<i32> 8 8
&[i32] 16 16
Vec<i32> 24 24
Result<(), Box<i32>> 8 16
需要注意的是&i32
, Box
, &[i32]
Vec<i32>
所有使用内部的非空的指针优化Option
!
这个答案现在已经过时; 在判别Option<T>
现在,已优化了在可能的情况。 (提供其余的信息仍然是有趣的,虽然)。
现在,一个Option
类型占据比任何其他相同量的空间enum
类型。 我不知道具体细节,但可以肯定的是表现为某种歧视工会。
来调整用于优化的内部表示的可能性正在由锈developpers考虑。
这里是一个dev的邮件列表上的相关讨论 ,发表帕特里克·沃尔顿:
我有点犹豫承诺枚举的特定位表示,因为这里有大量的空间,编译器优化。 例如,我们可能希望崩溃
Option<~int>
成可为空指针,我们可能希望崩溃Result<(),~str>
成可为空字符串,或者我们可能希望崩溃Either<u8,~str>
成1个字,假设弦永远不能占据前256个字节的地址空间。 我想了一会儿,也许这是最好的只是说,防锈枚举的位模式是不确定的,给我们尽可能多的房间尽可能与优化,以发挥。