Rust 程式設計視訊教程(進階)——014RefCell 和內部可變性

linghuyichong發表於2020-02-02

頭條地址:https://www.ixigua.com/i677586170644791348...
B站地址:https://www.bilibili.com/video/av81202308/

github地址:https://github.com/anonymousGiga/learn_rus...

1、內部可變性:允許在使用不可變引用時改變資料。

2、通過RefCell在執行時檢查借用規則(通常情況下,是在編譯時檢查借用規則),RefCell代表其資料的唯一所有權。
類似於Rc,RefCell只能用於單執行緒場景。

3、選擇Box、Rc或RefCell的理由:
Rc 允許相同資料有多個所有者;Box 和 RefCell 有單一所有者。
Box 允許在編譯時執行不可變或可變借用檢查;Rc僅允許在編譯時執行不可變借用檢查;RefCell 允許在執行時執行不可變或可變借用檢查。
因為 RefCell 允許在執行時執行可變借用檢查,所以我們可以在即便 RefCell 自身是不可變的情況下修改其內部的值。

4、內部可變性:不可變值的可變借用
例子:

#[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(10)), Rc::clone(&a)); //不可變引用

    *value.borrow_mut() += 10;   //可變,執行時成可變引用

    println!("a after = {:?}", a);
    println!("b after = {:?}", b);
    println!("c after = {:?}", c);
}

上述例子中,通過RefCell,我們可以擁有一個表面上不可變的List,但是通過RefCell中提供內部可變性方法來在需要時修改資料的方式。
執行結果:

a after = Cons(RefCell { value: 15 }, Nil)
b after = Cons(RefCell { value: 6 }, Cons(RefCell { value: 15 }, Nil))
c after = Cons(RefCell { value: 10 }, Cons(RefCell { value: 15 }, Nil))
本作品採用《CC 協議》,轉載必須註明作者和本文連結

令狐一衝

相關文章