-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Split interior mutability, mention OnceCell/OnceLock (#2573)
These types are really only useful as a static or in a user-defined type, neither of which are covered at this point.
- Loading branch information
Showing
5 changed files
with
81 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# `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()); | ||
} | ||
``` | ||
|
||
<details> | ||
|
||
- `Cell` is a simple means to ensure safety: it has a `set` method that takes | ||
`&self`. This needs no runtime check, but requires moving values, which can | ||
have its own cost. | ||
|
||
</details> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# `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 | ||
use std::cell::RefCell; | ||
fn main() { | ||
// Note that `cell` is NOT declared as mutable. | ||
let cell = RefCell::new(5); | ||
{ | ||
let mut cell_ref = cell.borrow_mut(); | ||
*cell_ref = 123; | ||
// This triggers an error at runtime. | ||
// let other = cell.borrow(); | ||
// println!("{}", *other); | ||
} | ||
println!("{cell:?}"); | ||
} | ||
``` | ||
|
||
<details> | ||
|
||
- `RefCell` enforces Rust's usual borrowing rules (either multiple shared | ||
references or a single exclusive reference) with a runtime check. In this | ||
case, all borrows are very short and never overlap, so the checks always | ||
succeed. | ||
|
||
- The extra block in the example is to end the borrow created by the call to | ||
`borrow_mut` before we print the cell. Trying to print a borrowed `RefCell` | ||
just shows the message `"{borrowed}"`. | ||
|
||
## More to Explore | ||
|
||
There are also `OnceCell` and `OnceLock`, which allow initialization on first | ||
use. Making these useful requires some more knowledge than students have at this | ||
time. | ||
|
||
</details> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters