mirror of
https://github.com/alrayyes/wiki.git
synced 2024-12-01 23:36:22 +00:00
62 lines
1.5 KiB
Markdown
62 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);
|
||
}
|
||
```
|