Auto merge of #34532 - jonmarkprice:master, r=steveklabnik
Book: Small grammatical and stylistic edits to book I've been reading [the book](https://doc.rust-lang.org/book/) and noticed a few small grammatical and stylistic issues which I've rolled into this pull request. I'm not sure if I should do so many small, unrelated edits in a single pull request but it seems like a lot of overhead for each small edit. Maybe one commit per edit but one pull request per file/section? Feedback is very much appreciated as this is my first pull request ever! r? @steveklabnik rollup
This commit is contained in:
commit
5e858f34df
3 changed files with 32 additions and 26 deletions
|
|
@ -290,7 +290,7 @@ lifetime parameters using three easily memorizable and unambiguous rules. This m
|
|||
acts as a shorthand for writing an item signature, while not hiding
|
||||
away the actual types involved as full local inference would if applied to it.
|
||||
|
||||
When talking about lifetime elision, we use the term *input lifetime* and
|
||||
When talking about lifetime elision, we use the terms *input lifetime* and
|
||||
*output lifetime*. An *input lifetime* is a lifetime associated with a parameter
|
||||
of a function, and an *output lifetime* is a lifetime associated with the return
|
||||
value of a function. For example, this function has an input lifetime:
|
||||
|
|
@ -335,11 +335,13 @@ fn print<'a>(s: &'a str); // expanded
|
|||
|
||||
fn debug(lvl: u32, s: &str); // elided
|
||||
fn debug<'a>(lvl: u32, s: &'a str); // expanded
|
||||
```
|
||||
|
||||
// In the preceding example, `lvl` doesn’t need a lifetime because it’s not a
|
||||
// reference (`&`). Only things relating to references (such as a `struct`
|
||||
// which contains a reference) need lifetimes.
|
||||
In the preceding example, `lvl` doesn’t need a lifetime because it’s not a
|
||||
reference (`&`). Only things relating to references (such as a `struct`
|
||||
which contains a reference) need lifetimes.
|
||||
|
||||
```rust,ignore
|
||||
fn substr(s: &str, until: u32) -> &str; // elided
|
||||
fn substr<'a>(s: &'a str, until: u32) -> &'a str; // expanded
|
||||
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ But, unlike a move, we can still use `v` afterward. This is because an `i32`
|
|||
has no pointers to data somewhere else, copying it is a full copy.
|
||||
|
||||
All primitive types implement the `Copy` trait and their ownership is
|
||||
therefore not moved like one would assume, following the ´ownership rules´.
|
||||
therefore not moved like one would assume, following the ‘ownership rules’.
|
||||
To give an example, the two following snippets of code only compile because the
|
||||
`i32` and `bool` types implement the `Copy` trait.
|
||||
|
||||
|
|
@ -290,6 +290,6 @@ let (v1, v2, answer) = foo(v1, v2);
|
|||
Ugh! The return type, return line, and calling the function gets way more
|
||||
complicated.
|
||||
|
||||
Luckily, Rust offers a feature, borrowing, which helps us solve this problem.
|
||||
It’s the topic of the next section!
|
||||
Luckily, Rust offers a feature which helps us solve this problem.
|
||||
It’s called borrowing and is the topic of the next section!
|
||||
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ let v = vec![];
|
|||
foo(&v);
|
||||
```
|
||||
|
||||
errors with:
|
||||
will give us this error:
|
||||
|
||||
```text
|
||||
error: cannot borrow immutable borrowed content `*v` as mutable
|
||||
|
|
@ -152,8 +152,8 @@ the thing `y` points at. You’ll notice that `x` had to be marked `mut` as well
|
|||
If it wasn’t, we couldn’t take a mutable borrow to an immutable value.
|
||||
|
||||
You'll also notice we added an asterisk (`*`) in front of `y`, making it `*y`,
|
||||
this is because `y` is a `&mut` reference. You'll also need to use them for
|
||||
accessing the contents of a reference as well.
|
||||
this is because `y` is a `&mut` reference. You'll need to use astrisks to
|
||||
access the contents of a reference as well.
|
||||
|
||||
Otherwise, `&mut` references are like references. There _is_ a large
|
||||
difference between the two, and how they interact, though. You can tell
|
||||
|
|
@ -179,7 +179,7 @@ As it turns out, there are rules.
|
|||
|
||||
# The Rules
|
||||
|
||||
Here’s the rules about borrowing in Rust:
|
||||
Here are the rules for borrowing in Rust:
|
||||
|
||||
First, any borrow must last for a scope no greater than that of the owner.
|
||||
Second, you may have one or the other of these two kinds of borrows, but not
|
||||
|
|
@ -208,12 +208,14 @@ With this in mind, let’s consider our example again.
|
|||
Here’s the code:
|
||||
|
||||
```rust,ignore
|
||||
let mut x = 5;
|
||||
let y = &mut x;
|
||||
fn main() {
|
||||
let mut x = 5;
|
||||
let y = &mut x;
|
||||
|
||||
*y += 1;
|
||||
*y += 1;
|
||||
|
||||
println!("{}", x);
|
||||
println!("{}", x);
|
||||
}
|
||||
```
|
||||
|
||||
This code gives us this error:
|
||||
|
|
@ -225,7 +227,7 @@ error: cannot borrow `x` as immutable because it is also borrowed as mutable
|
|||
```
|
||||
|
||||
This is because we’ve violated the rules: we have a `&mut T` pointing to `x`,
|
||||
and so we aren’t allowed to create any `&T`s. One or the other. The note
|
||||
and so we aren’t allowed to create any `&T`s. It's one or the other. The note
|
||||
hints at how to think about this problem:
|
||||
|
||||
```text
|
||||
|
|
@ -243,14 +245,16 @@ In Rust, borrowing is tied to the scope that the borrow is valid for. And our
|
|||
scopes look like this:
|
||||
|
||||
```rust,ignore
|
||||
let mut x = 5;
|
||||
fn main() {
|
||||
let mut x = 5;
|
||||
|
||||
let y = &mut x; // -+ &mut borrow of x starts here
|
||||
// |
|
||||
*y += 1; // |
|
||||
// |
|
||||
println!("{}", x); // -+ - try to borrow x here
|
||||
// -+ &mut borrow of x ends here
|
||||
let y = &mut x; // -+ &mut borrow of x starts here
|
||||
// |
|
||||
*y += 1; // |
|
||||
// |
|
||||
println!("{}", x); // -+ - try to borrow x here
|
||||
} // -+ &mut borrow of x ends here
|
||||
|
||||
```
|
||||
|
||||
The scopes conflict: we can’t make an `&x` while `y` is in scope.
|
||||
|
|
@ -269,12 +273,12 @@ println!("{}", x); // <- try to borrow x here
|
|||
```
|
||||
|
||||
There’s no problem. Our mutable borrow goes out of scope before we create an
|
||||
immutable one. But scope is the key to seeing how long a borrow lasts for.
|
||||
immutable one. So scope is the key to seeing how long a borrow lasts for.
|
||||
|
||||
## Issues borrowing prevents
|
||||
|
||||
Why have these restrictive rules? Well, as we noted, these rules prevent data
|
||||
races. What kinds of issues do data races cause? Here’s a few.
|
||||
races. What kinds of issues do data races cause? Here are a few.
|
||||
|
||||
### Iterator invalidation
|
||||
|
||||
|
|
@ -323,7 +327,7 @@ for i in &v {
|
|||
|
||||
We can’t modify `v` because it’s borrowed by the loop.
|
||||
|
||||
### use after free
|
||||
### Use after free
|
||||
|
||||
References must not live longer than the resource they refer to. Rust will
|
||||
check the scopes of your references to ensure that this is true.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue