wiki/content/20200929152628-refcell_t.md

63 lines
1.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
date: 20200929
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
Rusts 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
cant 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);
}
```