Box<T>是一个指针,Rust可以确定一个Box<T>的大小,从而可以使用Box<T>即一个栈上的指针,指向堆中无法在编译时确定大小的 类型T.
一个Cons例子:
假设一个枚举类,代表一个链表节点的两种属性:一种链接下一个节点,一种是Nil
#![allow(unused)] fn main() { use crate::List::{Cons,Nil}; enum List{ Cons(i32,List), Nil, } }
当cargo build 时,会报错
Compiling Box v0.1.0 (D:\rust\projects\Box)
error[E0072]: recursive type `List` has infinite size
--> src\main.rs:7:1
|
7 | enum List{
| ^^^^^^^^^^
8 | Cons(i32,List),
| ---- recursive without indirection
这是因为Rust 在编译时无法确定一个List的大小。
这时使用Box<T>,因为其是一个指针,所以在编译时便可确定大小,同时它还指向了堆中存放的List。
fn main() { let list = Cons(1,Box::new(Cons(2, Box::new(Cons(3,Box::new(Nil)))))); println!("list is {:?}",list); } use crate::List::{Cons, Nil}; #[derive(Debug)] enum List { Cons(i32, Box<List>), Nil, }
通过了编译。
Box<T>实现了Deref trait,允许将BOX<T>的值当作引用,并且当一个Box<T>的值离开作用域时,由于其实现了Drop trait,将导致其指向的堆中的数据也会被自动释放。
三种解引用转换
- 当 T:
Deref<Target=U>时,允许&T转换为&U - 当 T:
DerefMut<Target=U>时,允许&mut T转换为&mut U - 当 T:
Deref<Target=U>时,允许&mut T转换为&U.(可变转不可变)