RUST笔记:初识RefCell

下面是一个用到RC和RefCell的例子:

例子模拟餐厅的菜单的传递,菜单数据Order是Rc>>,一个RC引用了RefCell,RefCell又引用了一个集合了TableOrder结构体的Vec容器。外层的RC用于分享引用,但是RC是不可变引用,所以嵌套RefCell,我们不需要改变Rc里面的RefCell,但可以通过RefCell改变第三层数据。

*1 创建一个Order类型;

*2 为三类餐厅员工克隆该引用,因为Ref中的数据是可以共享的;

*3 改变第三层数据Vec,因为RefCell中的数据总是可变的,但是记得要把改变放在括号里,因为RefCell的借用规则是可变引用不可以和和其他引用共存,否则之前的引用会被析构掉,

*4 打印数据。

use std::borrow::BorrowMut;
use std::cell::RefCell;
use std::ops::Deref;
use std::rc::Rc;

#[derive(Debug)]
enum MenuItem {
    Drink,
    Salad,
}

#[derive(Debug)]
struct ItemOrder {
    item: MenuItem,
    quantity: u32,
}

#[derive(Debug)]
struct TableOrder {
    items: Vec,
}

fn new_table_order() ->TableOrder {
    TableOrder {
        items: vec![ItemOrder {
            item: MenuItem::Drink,
            quantity: 1,
        }],
    }

}
type Order = Rc>>;

#[derive(Debug)]
struct Chef(Order);


#[derive(Debug)]
struct Staff(Order);

#[derive(Debug)]
struct Accounting(Order);

fn main() {
    // *1
    let orders:Order = Rc::new(RefCell::new(vec![]));
    // *2
    let chef = Chef(Rc::clone(&orders));
    let staff = Staff(Rc::clone(&orders));
    let account = Accounting(Rc::clone(&orders));
    // *3
    let order = new_table_order();   
    {  (*orders).borrow_mut().push(order);    }
    
    // *4
    dbg!(chef.0.borrow());
    dbg!(staff.0.borrow());
    dbg!(account.0.borrow());
}

Refcell在运行时检查借用规则,引用具有无需关注数据本身的可变性,单一所有者。

Box在编译时检查借用规则,Box借用时只移动数据数据,所以是单一所有者。

Rc在编译时检查借用规则,多个引用所有权。

你可能感兴趣的:(rust,开发语言,后端)