mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-03-20 06:21:09 +02:00
interior-mutability.md: swap Cell/RefCell order and improve explanation (#2278)
Fixes #2249.
This commit is contained in:
parent
3fae0fd09f
commit
aa0201ccfd
@ -12,8 +12,36 @@ The "interior mutability" pattern allows exclusive (mutable) access behind a
|
|||||||
shared reference. The standard library provides several ways to do this, all
|
shared reference. The standard library provides several ways to do this, all
|
||||||
while still ensuring safety, typically by performing a runtime check.
|
while still ensuring safety, typically by performing a runtime check.
|
||||||
|
|
||||||
|
## `Cell`
|
||||||
|
|
||||||
|
`Cell` wraps a value and allows getting or setting the value using only a shared
|
||||||
|
reference to the `Cell`. However, it does not allow any references to the inner
|
||||||
|
value. Since there are no references, borrowing rules cannot be broken.
|
||||||
|
|
||||||
|
```rust,editable
|
||||||
|
use std::cell::Cell;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Note that `cell` is NOT declared as mutable.
|
||||||
|
let cell = Cell::new(5);
|
||||||
|
|
||||||
|
cell.set(123);
|
||||||
|
println!("{}", cell.get());
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## `RefCell`
|
## `RefCell`
|
||||||
|
|
||||||
|
`RefCell` allows accessing and mutating a wrapped value by providing alternative
|
||||||
|
types `Ref` and `RefMut` that emulate `&T`/`&mut T` without actually being Rust
|
||||||
|
references.
|
||||||
|
|
||||||
|
These types perform dynamic checks using a counter in the `RefCell` to prevent
|
||||||
|
existence of a `RefMut` alongside another `Ref`/`RefMut`.
|
||||||
|
|
||||||
|
By implementing `Deref` (and `DerefMut` for `RefMut`), these types allow calling
|
||||||
|
methods on the inner value without allowing references to escape.
|
||||||
|
|
||||||
```rust,editable
|
```rust,editable
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
@ -34,24 +62,6 @@ fn main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## `Cell`
|
|
||||||
|
|
||||||
`Cell` wraps a value and allows getting or setting the value, even with a shared
|
|
||||||
reference to the `Cell`. However, it does not allow any references to the value.
|
|
||||||
Since there are no references, borrowing rules cannot be broken.
|
|
||||||
|
|
||||||
```rust,editable
|
|
||||||
use std::cell::Cell;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
// Note that `cell` is NOT declared as mutable.
|
|
||||||
let cell = Cell::new(5);
|
|
||||||
|
|
||||||
cell.set(123);
|
|
||||||
println!("{}", cell.get());
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
The main thing to take away from this slide is that Rust provides _safe_ ways to
|
The main thing to take away from this slide is that Rust provides _safe_ ways to
|
||||||
|
Loading…
x
Reference in New Issue
Block a user