RUST笔记:初识RefCell

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

例子模拟餐厅的菜单的传递,菜单数据Order是Rc<RefCell<Vec<TableOrder>>>,一个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<ItemOrder>,
}

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

}
type Order = Rc<RefCell<Vec<TableOrder>>>;

#[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在编译时检查借用规则,多个引用所有权。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值