Box指针

  • Rust中变量都存储在栈中,而栈中的数据都是能确定数据大小的,也就说Rust仅能存储有确定大小(Sized)的变量

    enum List<T> {
        Cons(T, List<T>),
        Nil,
    }
    
    ...
    
    let list = Cons(5, Cons(5, Cons(5, Nil))); #无法通过编译
    
  • 当出现无固定大小的数据结构时,Box指针就有了用武之地,比如下面的数据结构

    enum List<T> {
        Cons(T,Box<List<T>>),
        Nil,
    }
    
    ...
    
    let list = Cons(5, Box::new(Cons(5, Box::new(Cons(5, Box::new(Nil)))))); #可以通过编译
    
    
  • Box的本质时利用指针将无法确定大小的递归嵌套型数据结构更改为确定大小的排列型数据结构

    image-20240528105925532

Ref指针

  • Rust中的借用规则决定了一份数据只能由一个所有者

  • 当出现数据需要由多个所有者时,Ref指针就能派上用场,比如下面的数据结构

    image-20240528110327860

  • Ref在不打破借用规则的情况下,内部维护一个引用计数器,只要引用计数器不归零,那么Ref指针包裹的数据就不会被释放,因此它允许一份数据被多个变量持有

  • Ref只能包裹不可变变量

RefCell指针

  • Rust中无法修改不可变变量的值

  • RefCell指针通过unsafe方法进行封装后使得被包裹不可变数据可以修改,其安全性由官方做出保证

  • RefCell跳过了编译时的借用规则检查,但在运行时仍需符合借用规则检查,否则会触发pannic

    let user = RefCell::new(String::from("coco"));
        let s1 = user.borrow();
        let s2 = user.borrow();
        let s3 = user.borrow_mut();
        let s4 = user.borrow_mut(); #运行时报错,只能持有一份数据的一个可变借用