mirror of
https://github.com/rust-lang-cn/book-cn.git
synced 2025-02-03 07:48:41 +08:00
Bumping in more section headers
This commit is contained in:
parent
6964610a5c
commit
92085ebd8f
@ -1,4 +1,4 @@
|
|||||||
# Ownership
|
## Ownership
|
||||||
|
|
||||||
Rust’s central feature is called ‘ownership’. It is a feature that is
|
Rust’s central feature is called ‘ownership’. It is a feature that is
|
||||||
straightforward to explain, but has deep implications for the rest of the
|
straightforward to explain, but has deep implications for the rest of the
|
||||||
@ -20,7 +20,7 @@ Once you understand ownership, you have a good foundation for understanding the
|
|||||||
features that make Rust unique. In this chapter, we'll learn ownership by going
|
features that make Rust unique. In this chapter, we'll learn ownership by going
|
||||||
through some examples, focusing on a very common data structure: strings.
|
through some examples, focusing on a very common data structure: strings.
|
||||||
|
|
||||||
## Variable binding scope
|
### Variable binding scope
|
||||||
|
|
||||||
We've walked through an example of a Rust program already in the tutorial
|
We've walked through an example of a Rust program already in the tutorial
|
||||||
chapter. Now that we’re past basic syntax, we won’t include all of the `fn
|
chapter. Now that we’re past basic syntax, we won’t include all of the `fn
|
||||||
@ -54,7 +54,7 @@ In other words, there are two important points in time here:
|
|||||||
At this point, things are similar to other programming languages. Now let’s
|
At this point, things are similar to other programming languages. Now let’s
|
||||||
build on top of this understanding by introducing the `String` type.
|
build on top of this understanding by introducing the `String` type.
|
||||||
|
|
||||||
## Strings
|
### Strings
|
||||||
|
|
||||||
String literals are convenient, but they aren’t the only way that you use
|
String literals are convenient, but they aren’t the only way that you use
|
||||||
strings. For one thing, they’re immutable. For another, not every string is
|
strings. For one thing, they’re immutable. For another, not every string is
|
||||||
@ -82,7 +82,7 @@ s.push_str(", world!"); // push_str() appends a literal to a String
|
|||||||
println!("{}", s); // This will print `hello, world!`
|
println!("{}", s); // This will print `hello, world!`
|
||||||
```
|
```
|
||||||
|
|
||||||
## Memory and allocation
|
### Memory and allocation
|
||||||
|
|
||||||
So, what’s the difference here? Why can `String` be mutated, but literals
|
So, what’s the difference here? Why can `String` be mutated, but literals
|
||||||
cannot? The difference comes down to how these two types deal with memory.
|
cannot? The difference comes down to how these two types deal with memory.
|
||||||
@ -144,7 +144,7 @@ This pattern has a profound impact on the way that Rust code is written. It may
|
|||||||
seem obvious right now, but things can get tricky in more advanced situations.
|
seem obvious right now, but things can get tricky in more advanced situations.
|
||||||
Let’s go over the first one of those right now.
|
Let’s go over the first one of those right now.
|
||||||
|
|
||||||
## Move
|
### Move
|
||||||
|
|
||||||
What would you expect this code to do?
|
What would you expect this code to do?
|
||||||
|
|
||||||
@ -245,7 +245,7 @@ into `s2`. So what actually happens looks like this:
|
|||||||
That solves our problem! With only `s2` valid, when it goes out of scope, it
|
That solves our problem! With only `s2` valid, when it goes out of scope, it
|
||||||
alone will free the memory, and we’re done.
|
alone will free the memory, and we’re done.
|
||||||
|
|
||||||
## Ownership Rules
|
### Ownership Rules
|
||||||
|
|
||||||
This leads us to the Ownership Rules:
|
This leads us to the Ownership Rules:
|
||||||
|
|
||||||
@ -257,7 +257,7 @@ Furthermore, there’s a design choice that’s implied by this: Rust will never
|
|||||||
automatically create ‘deep’ copies of your data. Therefore, any _automatic_
|
automatically create ‘deep’ copies of your data. Therefore, any _automatic_
|
||||||
copying can be assumed to be inexpensive.
|
copying can be assumed to be inexpensive.
|
||||||
|
|
||||||
## Clone
|
### Clone
|
||||||
|
|
||||||
But what if we _do_ want to deeply copy the `String`’s data and not just the
|
But what if we _do_ want to deeply copy the `String`’s data and not just the
|
||||||
`String` itself? There’s a common method for that: `clone()`. We will discuss
|
`String` itself? There’s a common method for that: `clone()`. We will discuss
|
||||||
@ -284,7 +284,7 @@ When you see a call to `clone()`, you know that some arbitrary code is being
|
|||||||
executed, and that code may be expensive. It’s a visual indicator that something
|
executed, and that code may be expensive. It’s a visual indicator that something
|
||||||
different is going on here.
|
different is going on here.
|
||||||
|
|
||||||
## Copy
|
### Copy
|
||||||
|
|
||||||
There’s one last wrinkle that we haven’t talked about yet. This code works:
|
There’s one last wrinkle that we haven’t talked about yet. This code works:
|
||||||
|
|
||||||
@ -322,7 +322,7 @@ but nothing that requires allocation or is some form of resource is `Copy`. Here
|
|||||||
* Tuples, but only if they contain types which are also `Copy`. `(i32, i32)`
|
* Tuples, but only if they contain types which are also `Copy`. `(i32, i32)`
|
||||||
is `Copy`, but `(i32, String)` is not.
|
is `Copy`, but `(i32, String)` is not.
|
||||||
|
|
||||||
## Ownership and functions
|
### Ownership and functions
|
||||||
|
|
||||||
Passing a value to a function has similar semantics as assigning it:
|
Passing a value to a function has similar semantics as assigning it:
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# References and Borrowing
|
## References and Borrowing
|
||||||
|
|
||||||
At the end of the last section, we had some example Rust that wasn’t very
|
At the end of the last section, we had some example Rust that wasn’t very
|
||||||
good. Here it is again:
|
good. Here it is again:
|
||||||
@ -117,7 +117,7 @@ error: cannot borrow immutable borrowed content `*some_string` as mutable
|
|||||||
Just like bindings are immutable by default, so are references. We’re not
|
Just like bindings are immutable by default, so are references. We’re not
|
||||||
allowed to modify something we have a reference to.
|
allowed to modify something we have a reference to.
|
||||||
|
|
||||||
## Mutable references
|
### Mutable references
|
||||||
|
|
||||||
We can fix this bug! Just a small tweak:
|
We can fix this bug! Just a small tweak:
|
||||||
|
|
||||||
@ -209,7 +209,7 @@ Whew! We _also_ cannot have a mutable reference while we have an immutable one.
|
|||||||
Users of an immutable reference don’t expect the values to suddenly change out
|
Users of an immutable reference don’t expect the values to suddenly change out
|
||||||
from under them! Multiple immutable references are okay, however.
|
from under them! Multiple immutable references are okay, however.
|
||||||
|
|
||||||
## Dangling references
|
### Dangling references
|
||||||
|
|
||||||
In languages with pointers, it’s easy to create a “dangling pointer” by freeing
|
In languages with pointers, it’s easy to create a “dangling pointer” by freeing
|
||||||
some memory while keeping around a pointer to that memory. In Rust, by
|
some memory while keeping around a pointer to that memory. In Rust, by
|
||||||
@ -240,7 +240,7 @@ error[E0106]: missing lifetime specifier
|
|||||||
5 | fn dangle() -> &String {
|
5 | fn dangle() -> &String {
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
|
|
||||||
= help: this function's return type contains a borrowed value, but there is no
|
= help: this function's return type contains a borrowed value, but there is no
|
||||||
value for it to be borrowed from
|
value for it to be borrowed from
|
||||||
= help: consider giving it a 'static lifetime
|
= help: consider giving it a 'static lifetime
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ fn no_dangle() -> String {
|
|||||||
|
|
||||||
This works, no problem. Ownership is moved out, nothing is deallocated.
|
This works, no problem. Ownership is moved out, nothing is deallocated.
|
||||||
|
|
||||||
## The Rules of References
|
### The Rules of References
|
||||||
|
|
||||||
Here’s a recap of what we’ve talked about:
|
Here’s a recap of what we’ve talked about:
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Slices
|
## Slices
|
||||||
|
|
||||||
So far, we’ve talked about types that have ownership, like `String`, and ones
|
So far, we’ve talked about types that have ownership, like `String`, and ones
|
||||||
that don’t, like `&String`. There is another kind of type which does not have
|
that don’t, like `&String`. There is another kind of type which does not have
|
||||||
@ -114,7 +114,7 @@ around which need to be kept in sync.
|
|||||||
|
|
||||||
Luckily, Rust has a solution to this problem: string slices.
|
Luckily, Rust has a solution to this problem: string slices.
|
||||||
|
|
||||||
# String slices
|
## String slices
|
||||||
|
|
||||||
A string slice looks like this:
|
A string slice looks like this:
|
||||||
|
|
||||||
@ -253,7 +253,7 @@ The type of `s` here is `&str`: It’s a slice, pointing to that specific point
|
|||||||
of the binary. This is also why string literals are immutable; `&str` is an
|
of the binary. This is also why string literals are immutable; `&str` is an
|
||||||
immutable reference.
|
immutable reference.
|
||||||
|
|
||||||
## String slices as arguments
|
### String slices as arguments
|
||||||
|
|
||||||
Knowing that you can take slices of both literals and `String`s leads us to
|
Knowing that you can take slices of both literals and `String`s leads us to
|
||||||
one more improvement on `first_word()`, and that’s its signature:
|
one more improvement on `first_word()`, and that’s its signature:
|
||||||
@ -303,7 +303,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
# Other slices
|
## Other slices
|
||||||
|
|
||||||
String slices, as you might imagine, are specific to strings. But there’s a more
|
String slices, as you might imagine, are specific to strings. But there’s a more
|
||||||
general slice type, too. Consider arrays:
|
general slice type, too. Consider arrays:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Method Syntax
|
## Method Syntax
|
||||||
|
|
||||||
In the last section on ownership, we made several references to ‘methods’.
|
In the last section on ownership, we made several references to ‘methods’.
|
||||||
Methods look like this:
|
Methods look like this:
|
||||||
@ -34,7 +34,7 @@ The nested-functions version reads in reverse: the program executes `f()`, then
|
|||||||
Before we get into the details, let’s talk about how to define your own
|
Before we get into the details, let’s talk about how to define your own
|
||||||
methods.
|
methods.
|
||||||
|
|
||||||
## Defining methods
|
### Defining methods
|
||||||
|
|
||||||
We can define methods with the `impl` keyword. `impl` is short for
|
We can define methods with the `impl` keyword. `impl` is short for
|
||||||
‘implementation’. Doing so looks like this:
|
‘implementation’. Doing so looks like this:
|
||||||
@ -123,7 +123,7 @@ rarely used. An example of a time to do that would be if we wanted to have a
|
|||||||
method that would transform `self` into something else and prevent other code
|
method that would transform `self` into something else and prevent other code
|
||||||
from using the value of `self` after the transformation happens.
|
from using the value of `self` after the transformation happens.
|
||||||
|
|
||||||
### Methods and automatic referencing
|
#### Methods and automatic referencing
|
||||||
|
|
||||||
We’ve left out an important detail. It’s in this line of the example:
|
We’ve left out an important detail. It’s in this line of the example:
|
||||||
|
|
||||||
@ -145,12 +145,12 @@ or `&mut`s to match the signature. In other words, these are the same:
|
|||||||
# x: f64,
|
# x: f64,
|
||||||
# y: f64,
|
# y: f64,
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
# impl Point {
|
# impl Point {
|
||||||
# fn distance(&self, other: &Point) -> f64 {
|
# fn distance(&self, other: &Point) -> f64 {
|
||||||
# let x_squared = f64::powi(other.x - self.x, 2);
|
# let x_squared = f64::powi(other.x - self.x, 2);
|
||||||
# let y_squared = f64::powi(other.y - self.y, 2);
|
# let y_squared = f64::powi(other.y - self.y, 2);
|
||||||
#
|
#
|
||||||
# f64::sqrt(x_squared + y_squared)
|
# f64::sqrt(x_squared + y_squared)
|
||||||
# }
|
# }
|
||||||
# }
|
# }
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Option
|
## Option
|
||||||
|
|
||||||
Now that we have had an introduction to enums, let's combine them with a
|
Now that we have had an introduction to enums, let's combine them with a
|
||||||
feature that we talked a little bit about in the previous chapter: generics.
|
feature that we talked a little bit about in the previous chapter: generics.
|
||||||
@ -18,7 +18,7 @@ The inventor of this concept has this to say:
|
|||||||
> implement. This has led to innumerable errors, vulnerabilities, and system
|
> implement. This has led to innumerable errors, vulnerabilities, and system
|
||||||
> crashes, which have probably caused a billion dollars of pain and damage in
|
> crashes, which have probably caused a billion dollars of pain and damage in
|
||||||
> the last forty years.
|
> the last forty years.
|
||||||
>
|
>
|
||||||
> - Tony Hoare "Null References: The Billion Dollar Mistake"
|
> - Tony Hoare "Null References: The Billion Dollar Mistake"
|
||||||
|
|
||||||
The problem with null values is twofold: first, a value can be null or not, at
|
The problem with null values is twofold: first, a value can be null or not, at
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Match
|
## Match
|
||||||
|
|
||||||
Rust has an extremely powerful control-flow operator: `match`. It allows us to
|
Rust has an extremely powerful control-flow operator: `match`. It allows us to
|
||||||
compare a value against a series of patterns and then execute code based on
|
compare a value against a series of patterns and then execute code based on
|
||||||
@ -212,7 +212,7 @@ inside, and then execute code based on it. It's a bit tricky at first, but
|
|||||||
once you get used to it, you'll wish you had it in languages that don't support
|
once you get used to it, you'll wish you had it in languages that don't support
|
||||||
it. It's consistently a user favorite.
|
it. It's consistently a user favorite.
|
||||||
|
|
||||||
## Matches are exhaustive
|
### Matches are exhaustive
|
||||||
|
|
||||||
There's one other aspect of `match` we didn't talk about. Consider this version
|
There's one other aspect of `match` we didn't talk about. Consider this version
|
||||||
of `plus_one()`:
|
of `plus_one()`:
|
||||||
@ -243,7 +243,7 @@ every last option possible in order to be valid. Especially in the case of
|
|||||||
have null and thus making the billion-dollar mistake we discussed in the
|
have null and thus making the billion-dollar mistake we discussed in the
|
||||||
previous section.
|
previous section.
|
||||||
|
|
||||||
## The _ placeholder
|
### The _ placeholder
|
||||||
|
|
||||||
What if we don't care about all of the possible values, though? Especially when
|
What if we don't care about all of the possible values, though? Especially when
|
||||||
there are a lot of possible values for a type: a `u8` can have valid values of
|
there are a lot of possible values for a type: a `u8` can have valid values of
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# if let
|
## if let
|
||||||
|
|
||||||
There's one more advanced control flow structure we haven't discussed: `if
|
There's one more advanced control flow structure we haven't discussed: `if
|
||||||
let`. Imagine we're in a situation like this:
|
let`. Imagine we're in a situation like this:
|
||||||
|
Loading…
Reference in New Issue
Block a user