mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-03-20 14:31:15 +02:00
Improve dangling reference example and move to its own slide (#2518)
The current example demonstrating how rustc prevents dangling references is really gross and hard to read (my own fault lol, I wrote that example). I finally realized that there's a much simpler, easier to read way of expressing the same thing. I also moved this to its own slide after the reference slides so that we can call it out as an early example of the borrow checker. I then call back to this example in the borrow checker slide to remind students that the aliasing rule isn't the only thing the borrow checker is enforcing.
This commit is contained in:
parent
5bf04964f6
commit
2ff30edd93
@ -57,6 +57,7 @@
|
||||
- [Exclusive References](references/exclusive.md)
|
||||
- [Slices](references/slices.md)
|
||||
- [Strings](references/strings.md)
|
||||
- [Reference Validity](references/dangling.md)
|
||||
- [Exercise: Geometry](references/exercise.md)
|
||||
- [Solution](references/solution.md)
|
||||
- [User-Defined Types](user-defined-types.md)
|
||||
|
@ -4,8 +4,23 @@ minutes: 10
|
||||
|
||||
# Borrow Checking
|
||||
|
||||
Rust's _borrow checker_ puts constraints on the ways you can borrow values. For
|
||||
a given value, at any time:
|
||||
Rust's _borrow checker_ puts constraints on the ways you can borrow values.
|
||||
We've already seen that a reference cannot _outlive_ the value it borrows:
|
||||
|
||||
<!-- mdbook-xgettext: skip -->
|
||||
|
||||
```rust,editable,compile_fail
|
||||
fn main() {
|
||||
let x_ref = {
|
||||
let x = 10;
|
||||
&x
|
||||
};
|
||||
println!("x: {x_ref}");
|
||||
}
|
||||
```
|
||||
|
||||
There's also a second main rule that the borrow checker enforces: The _aliasing_
|
||||
rule. For a given value, at any time:
|
||||
|
||||
- You can have one or more shared references to the value, _or_
|
||||
- You can have exactly one exclusive reference to the value.
|
||||
@ -29,6 +44,9 @@ fn main() {
|
||||
|
||||
<details>
|
||||
|
||||
- The "outlives" rule was demonstrated previously when we first looked at
|
||||
references. We review it here to show students that the borrow checking is
|
||||
following a few different rules to validate borrowing.
|
||||
- Note that the requirement is that conflicting references not _exist_ at the
|
||||
same point. It does not matter where the reference is dereferenced.
|
||||
- The above code does not compile because `a` is borrowed as mutable (through
|
||||
|
39
src/references/dangling.md
Normal file
39
src/references/dangling.md
Normal file
@ -0,0 +1,39 @@
|
||||
---
|
||||
minutes: 3
|
||||
---
|
||||
|
||||
# Reference Validity
|
||||
|
||||
Rust enforces a number of rules for references that make them always safe to
|
||||
use. One rule is that references can never be `null`, making them safe to use
|
||||
without `null` checks. The other rule we'll look at for now is that references
|
||||
can't _outlive_ the data they point to.
|
||||
|
||||
<!-- mdbook-xgettext: skip -->
|
||||
|
||||
```rust,editable,compile_fail
|
||||
fn main() {
|
||||
let x_ref = {
|
||||
let x = 10;
|
||||
&x
|
||||
};
|
||||
println!("x: {x_ref}");
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
|
||||
- This slide gets students thinking about references as not simply being
|
||||
pointers, since Rust has different rules for references than other languages.
|
||||
|
||||
- We'll look at the rest of Rust's borrowing rules on day 3 when we talk about
|
||||
Rust's ownership system.
|
||||
|
||||
## More to Explore
|
||||
|
||||
- Rust's equivalent of nullability is the `Option` type, which can be used to
|
||||
make any type "nullable" (not just references/pointers). We haven't yet
|
||||
introduced enums or pattern matching, though, so try not to go into too much
|
||||
detail about this here.
|
||||
|
||||
</details>
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
minutes: 10
|
||||
minutes: 7
|
||||
---
|
||||
|
||||
# Exclusive References
|
||||
|
@ -25,17 +25,6 @@ A shared reference to a type `T` has type `&T`. A reference value is made with
|
||||
the `&` operator. The `*` operator "dereferences" a reference, yielding its
|
||||
value.
|
||||
|
||||
Rust will statically forbid dangling references:
|
||||
|
||||
<!-- mdbook-xgettext: skip -->
|
||||
|
||||
```rust,editable,compile_fail
|
||||
fn x_axis(x: &i32) -> &(i32, i32) {
|
||||
let point = (*x, 0);
|
||||
return &point;
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
|
||||
- References can never be null in Rust, so null checking is not necessary.
|
||||
|
Loading…
x
Reference in New Issue
Block a user