rust语言学习笔记(指针一)Box<T>(堆分配,独占所有)
把一个值放到堆上,并由一个唯一所有者管理它。
1.1Box<T>特点:
(1)堆分配
(2)唯一所有权
(3)单线程
1.2 自动解引用
Box<T>实现了Deref,支持自动解引用操作,比如*y。
letx=5;lety=Box::new(x);assert_eq!(5,*y);1.3Box<T>用途:
1.3.1 无法确定大小的值(递归类型)
#[derive(Debug)]enumList{Cons(i32,Box<List>),Nil,}fnmain(){letlist=List::Cons(1,Box::new(List::Cons(2,Box::new(List::Nil))));println!("{:?}",list);}1.3.2 运行时多态(trait object)
traitMyPrint{fnprint(&self);}structm1{}implMyPrintform1{fnprint(&self){println!("m1");}}structm2{}implMyPrintform2{fnprint(&self){println!("m2");}}fnmain(){letml:Vec<Box<dynMyPrint>>=vec![Box::new(m1{}),Box::new(m2{})];foriinml{i.print();}}1.3.3 大对象移动
// 定义一个大结构体,使用 Vec 存储数据以避免栈溢出#[derive(Debug)]structBigData{buffer:Vec<u8>,// 使用 Vec 在堆上存储数据}implBigData{fnnew(size:usize)->Self{Self{buffer:vec![0;size],// Vec 初始化直接在堆上分配}}}// 该函数获取 Box 的所有权fnprocess_data(data:Box<BigData>){println!("数据处理中,缓冲区大小: {} bytes",data.buffer.len());// 当函数结束时,data 离开作用域,Box 自动释放堆上的内存}fnmain(){// 1. 在堆上分配大对象// Box::new 会将 BigData 移动到堆上,main 函数的栈上只保留一个指针letmy_data=Box::new(BigData::new(1024*1024));// 1 MBprintln!("准备移动大对象...");// 2. 移动所有权// 这里发生的是"移动"而非"拷贝"。// 仅拷贝了栈上的指针(8字节),而不是拷贝 1MB 的数据。// my_data 在此之后不再有效。process_data(my_data);// println!("{:?}", my_data.buffer.len()); // 编译错误!my_data 的所有权已移走}