在 Rust 中,引用永远不能为 null,因此如果您确实需要 null,例如链表,请使用以下Option
类型:
struct Element {
value: i32,
next: Option<Box<Element>>,
}
与简单的指针相比,在内存分配和取消引用的步骤方面涉及多少开销?编译器/运行时是否有一些“魔法”可以Option
免费使用,或者比Option
使用相同结构在非核心库中自行实现enum
或将指针包装在向量中的成本更低?
在 Rust 中,引用永远不能为 null,因此如果您确实需要 null,例如链表,请使用以下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