关于RefCell<T>用法的简单对比示例

115 阅读1分钟

RefCell<T> 的主要用途是在不可变引用与可变引用之间建立一个动态的边界, 以允许在不违反 Rust 的安全规则的情况下修改不可变数据。

示例1

借用规则的一个推论是:当有一个不可变值时,不能可变地借用它。 例如,如下代码不能编译:

fn main() {
    let x = 5;
    // 会报错
    // cannot borrow `x` as mutable, as it is not declared as mutable
    // help: consider changing this to be mutable: `mut x`
    let y = &mut x;
}

示例2

以可变借用借出,再修改,是可以的:

fn main() {
    let mut x = 5;

    let y = &mut x;
    println!("{:#?}", y);
    // 5

    *y += 5;
    println!("{:#?}", y);
    // 10
}

示例3

通过RefCell<T>修改不可变数据。

use std::{cell::RefCell};

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

    // 只有把这块注释掉,下面一块代码才可以运行
    // 否则会报错:
    // thread 'main' panicked at 'already borrowed: BorrowMutError', main.rs:11:19
    // 也就是说,在运行时,rust 还是会去做借用规则的检查,如果检查出错,这下不是编译不通过了,而是直接 panic
    // 这里已经作为不可变借出了,所以之后就不能再作为可变借出了
    // let y = x.borrow();
    // println!("{:#?}", y);
    // // 5

    // 这里可以通过 值 自己内部的方法 borrow_mut 来获取可变借用
    // 再通过可变借用修改值
    let mut y = x.borrow_mut();
    println!("{:#?}", y);
    // 5

    *y += 5;
    println!("{:#?}", y);
    // 10
}