mirror of
https://github.com/alrayyes/wiki.git
synced 2024-11-22 11:36:23 +00:00
63 lines
1.5 KiB
Markdown
63 lines
1.5 KiB
Markdown
|
---
|
|||
|
id: 16e7cc98-b9fb-40c3-b2cf-41d3035275be
|
|||
|
title: RefCell\<T\>
|
|||
|
---
|
|||
|
|
|||
|
# Introduction
|
|||
|
|
|||
|
*Interior mutability* is a design pattern in Rust that allows you to
|
|||
|
mutate data even when there are immutable references to that data;
|
|||
|
normally, this action is disallowed by the borrowing rules. To mutate
|
|||
|
data, the pattern uses `unsafe` code inside a data structure to bend
|
|||
|
Rust’s usual rules that govern mutation and borrowing. We can use types
|
|||
|
that use the interior mutability pattern when we can ensure that the
|
|||
|
borrowing rules will be followed at runtime, even though the compiler
|
|||
|
can’t guarantee that. The `unsafe` code involved is then wrapped in a
|
|||
|
safe API, and the outer type is still immutable.
|
|||
|
|
|||
|
# Reason to choose RefCell\<T\>
|
|||
|
|
|||
|
Because `RefCell<T>` allows mutable borrows checked at runtime, you can
|
|||
|
mutate the value inside the `RefCell<T>` even when the `RefCell<T>` is
|
|||
|
immutable.
|
|||
|
|
|||
|
# Example
|
|||
|
|
|||
|
This won't compile:
|
|||
|
|
|||
|
``` rust
|
|||
|
fn main() {
|
|||
|
let x = 5;
|
|||
|
let y = &mut x;
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
This will:
|
|||
|
|
|||
|
``` rust
|
|||
|
#[derive(Debug)]
|
|||
|
enum List {
|
|||
|
Cons(Rc<RefCell<i32>>, Rc<List>),
|
|||
|
Nil,
|
|||
|
}
|
|||
|
|
|||
|
use crate::List::{Cons, Nil};
|
|||
|
use std::cell::RefCell;
|
|||
|
use std::rc::Rc;
|
|||
|
|
|||
|
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(3)), Rc::clone(&a));
|
|||
|
let c = Cons(Rc::new(RefCell::new(4)), Rc::clone(&a));
|
|||
|
|
|||
|
*value.borrow_mut() += 10;
|
|||
|
|
|||
|
println!("a after = {:?}", a);
|
|||
|
println!("b after = {:?}", b);
|
|||
|
println!("c after = {:?}", c);
|
|||
|
}
|
|||
|
```
|