Box

Box

C里面是通过malloc/free手动管理堆上内存空间的,而Rust则有多种方式,其中最常用的一种就是Box,通过Box::new()可以在堆上申请一块内存空间,不像C里面一样堆上空间需要手动调用free释放,Rust中是在编译期编译器借助lifetime对堆内存生命期进行分析,在生命期结束时自动插入free。当前Rust底层即Box背后是调用jemalloc来做内存管理的,所以堆上空间是不需要程序员手动去管理释放的。很多时候你被编译器虐得死去活来时,那些borrow, move, lifetime错误其实就是编译器在教你认识内存布局,教你用lifetime规则去控制内存。大多数带GC的面向对象语言里面的对象都是借助box来实现的,比如常见的动态语言Python/Ruby/JavaScript等,其宣称的"一切皆对象(Everything is an object)",里面所谓的对象基本上都是boxed value

boxed值相对于unboxed,内存占用空间会大些,同时访问值的时候也需要先进行unbox,即对指针进行解引用再获取真正存储的值,所以内存访问开销也会大些。既然boxed值既费空间又费时间,为什么还要这么做呢?因为通过box,所有对象看起来就像是以相同大小存储的,因为只需要存储一个指针就够了,应用程序可以同等看待各种值,而不用去管实际存储是多大的值,如何申请和释放相应资源。

Box是堆上分配的内存,通过Box::new()会创建一个堆空间并返回一个指向堆空间的指针,nightly版本中引入box关键词,可以用来取代Box::new()申请一个堆空间,也可以用在模式匹配上面:

#![feature(box_syntax, box_patterns)]
fn main() {
   let boxed = Some(box 5);
   match boxed {
       Some(box unboxed) => println!("Some {}", unboxed),
       None => println!("None"),
   }
}
下一页