Box <T>
是一个智能指针,指向在类型为T的堆上分配的数据。Box <T>
允许将数据存储在堆而不是堆栈上。Box <T>
是一个拥有的指针。
除了将数据存储在堆上之外,Box
没有性能开销。
当Box
离开作用域时,会调用析构函数来销毁所有内部对象并释放内存。
使用Box <T>
将数据存储在堆上。
主要是,Box <T>
用于在堆上存储数据。下面通过一个简单的例子来理解这一点:
fn main()
{
let a = Box :: new(1);
print!("value of a is : {}",a);
}
执行上面示例代码,得到以下结果 -
value of a is : 1
在上面的例子中,a
包含指向数据1
的Box
的值。如果访问Box
的值,则程序打印‘1’。 当程序结束时,Box
被解除分配。Box
存储在堆栈中,它指向的数据存储在堆上。
下面来看看上面例子的图解表示:
Cons列表
Cons
代表“构造功能”。Cons
列表是一个数据结构,用于从两个参数构造一个新对,这对称为List
。- 假设有两个元素
x
和y
,那么cons
函数cons “x到y”
表示通过首先放置元素x
,然后是元素y
来构造新容器。 Cons
列表包含两个元素,即当前项和最后一项。 由于Nil
不包含下一个项目,因此缺点列表的最后一项是Nil
。
现在,创建包含cons
列表的枚举。
enum List
{
cons(i32, List),
Nil,
}
在上面的代码中,创建了List
类型的枚举,其中包含i32
值的cons
列表数据结构。
现在,在以下示例中使用上面的List
类型:
enum List {
Cons(i32, List),
Nil,
}
use List::{Cons, Nil};
fn main()
{
let list = List::Cons(1,Cons(2,Cons(3,Nil)));
for i in list.iter()
{
print!("{}",i);
}
}
执行上示例代码,得到以下结果 -
在上面的示例中,Rust编译器抛出错误“具有无限大小”,因为List类型包含递归的变体。 因此,Rust无法找出存储List值所需的空间。 使用Box <T>
可以克服无限大小的问题。
使用Box <T>
获取递归类型的大小
Rust无法确定存储递归数据类型需要多少空间。 Rust编译器在前一种情况下显示错误:
= help: insert indirection (e.g., a 'Box', 'Rc', or '&') at some point to make 'List' representable
在上面的例子中,可以使用Box <T>
指针,因为编译器知道Box <T>
指针需要多少空间。 Box <T>
指针的大小在程序执行期间不会改变。 Box <T>
指针指向将存储在堆上而不是cons
变量中的List值。 Box <T>
指针可以直接放在cons
变量中。
下面来看一个简单的例子 -
#[derive(Debug)]
enum List {
Cons(i32, Box<List>),
Nil,
}
use List::{Cons, Nil};
fn main()
{
let list = Cons(1,Box::new(Cons(2,Box::new(Cons(3,Box::new(Nil))))));
print!("{:?}",list);
}
执行上面示例代码,得到以输出结果如下 -
Cons(1, Cons(2, Cons(3, Nil)))