RefCell介绍

  1. 内部可变性:允许在使用不可变引用的时候改变数据
  2. 通过RefCell运行时 检查借用规则(通常情况下是在编译的过程中检查借用规则)
    RefCell代表其数据的唯一所有权
    Rc和RefCell都只能用于单线程场景
  3. 选择Box、Rc或者RefCell的理由:
    (1). Rc允许数据有多个所有者;Box或者RefCell仅仅只有一个单一所有者
    (2). Box允许在编译过程中执行不可变或者可变借用检查;Rc仅仅允许在编译时执行
    不可变借用检查;RefCell允许在运行过程中执行不可变或者可变借用检查
    (3).RefCell允许在运行时执行可变借用检查,所以RefCell可在数据本身不可变的过程
    中执行修改内部值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#[derive(Debug)]
enum List {
Cons(Rc<RefCell<i32>>,Rc<List>),
Nil,
}

use crate::List::{Cons,Nil};
use std::rc::Rc;
use std::cell::RefCell;

fn main() {
let value = Rc::new(RefCell::new(5));

let a = Rc::new(Cons(Rc::clone(&value),Rc::new(Nil)));
let b = Cons(Rc::new(RefCell::new(6)),Rc::clone(&a));
let c = Cons(Rc::new(RefCell::new(7)),Rc::clone(&a));
println!("a before = {:?}",a); //5
println!("b before = {:?}",b); //6
println!("c before = {:?}",c); //7

*value.borrow_mut() += 10; //对RefCell内部值进行修改
println!("a after = {:?}",a); //15 //外部不可变性,内部的可变性
//Rc<RefCell>是外部的,是不可变的;而内部的value是可变的
println!("b after = {:?}",b); //6
println!("c after = {:?}",c); //7
}