mirror of
https://github.com/rust-lang-cn/book-cn.git
synced 2025-01-23 23:50:25 +08:00
Standardize on using asterisks for emphasis
This commit is contained in:
parent
ef1556390b
commit
e8e42f79cb
@ -71,7 +71,7 @@ note: prior assignment occurs here
|
||||
|
||||
This is our first example of the compiler helping us find an error in our
|
||||
program! Compiler errors can be frustrating. Keep in mind that they only mean
|
||||
your program isn't safely doing what you want it to do yet; they do _not_ mean
|
||||
your program isn't safely doing what you want it to do yet; they do *not* mean
|
||||
that you're not a good programmer! Experienced Rustaceans still get compiler
|
||||
errors. The Rust compiler is trying to help your program be the very best.
|
||||
|
||||
@ -121,7 +121,7 @@ lead to bugs. If one part of our code operates on an assumption that a value
|
||||
will never change, and another part of our code changes that value, it's
|
||||
possible that the first part of the code won't do what it was designed to do.
|
||||
This cause of bugs can be difficult to track down after the fact, especially
|
||||
when the second piece of code only changes the value _sometimes_.
|
||||
when the second piece of code only changes the value *sometimes*.
|
||||
|
||||
In Rust, we can trust that a value we say won't change really won't change,
|
||||
because the compiler is enforcing that guarantee for us. When reading and
|
||||
@ -537,7 +537,7 @@ fn main() {
|
||||
|
||||
While arrays can be useful since they are a primitive type so using them can be
|
||||
very fast, they aren't as flexible as the vector type. The vector type is a
|
||||
similar collection type provided by the standard library that _is_ allowed to
|
||||
similar collection type provided by the standard library that *is* allowed to
|
||||
grow or shrink in size. If you're unsure whether to use an array or a vector,
|
||||
you should probably go with a vector, and we'll discuss them in more detail in
|
||||
Chapter 8.
|
||||
@ -645,7 +645,7 @@ body begins and ends.
|
||||
We can call any function we’ve defined by entering its name followed by a pair
|
||||
of parentheses. Since `another_function` is defined in the program, it can be
|
||||
called from inside the `main` function. Note that we defined
|
||||
`another_function` _after_ the `main` function in our source code; we could
|
||||
`another_function` *after* the `main` function in our source code; we could
|
||||
have defined it before as well. Rust doesn’t care where you define your
|
||||
functions, only that they are defined somewhere.
|
||||
|
||||
@ -696,7 +696,7 @@ specify the type of `x` as `i32`. When we pass `5` to `another_function`,
|
||||
the `println!` macro puts `5` where the pair of curly braces were in the format
|
||||
string.
|
||||
|
||||
In function signatures, we _must_ declare the type. This is a deliberate
|
||||
In function signatures, we *must* declare the type. This is a deliberate
|
||||
decision in the design of Rust; requiring type annotations in function
|
||||
definitions means the compiler almost never needs you to use them elsewhere in
|
||||
the code in order to figure out what you mean.
|
||||
@ -1068,7 +1068,7 @@ $ cargo run
|
||||
condition was false
|
||||
```
|
||||
|
||||
It’s also worth noting that the condition here _must_ be a `bool`. To see what
|
||||
It’s also worth noting that the condition here *must* be a `bool`. To see what
|
||||
happens if the condition isn't a `bool`, try running this code:
|
||||
|
||||
Filename: src/main.rs
|
||||
@ -1443,5 +1443,5 @@ programs to do things like:
|
||||
* Print the lyrics to the Christmas carol *The Twelve Days of Christmas*,
|
||||
taking advantage of the repetition in the song.
|
||||
|
||||
When you're ready to move on, we'll talk about a concept in Rust that _doesn't_
|
||||
When you're ready to move on, we'll talk about a concept in Rust that *doesn't*
|
||||
commonly exist in other programming languages: ownership.
|
||||
|
@ -115,7 +115,7 @@ let s = "hello";
|
||||
|
||||
The variable binding `s` refers to a string literal, where the value of the
|
||||
string is hard coded into the text of our program. The binding is valid from
|
||||
the point at which it’s declared until the end of the current _scope_. That is:
|
||||
the point at which it’s declared until the end of the current *scope*. That is:
|
||||
|
||||
```rust
|
||||
{ // s is not valid here, it’s not yet declared
|
||||
@ -231,7 +231,7 @@ return the memory. Rust calls `drop` automatically at the closing `}`.
|
||||
> Initialization* in C++, or RAII for short. While they are very similar,
|
||||
> Rust’s take on this concept has a number of differences, so we don’t tend
|
||||
> to use the same term. If you’re familiar with this idea, keep in mind that it
|
||||
> is _roughly_ similar in Rust, but not identical.
|
||||
> is *roughly* similar in Rust, but not identical.
|
||||
|
||||
This pattern has a profound impact on the way that Rust code is written. It may
|
||||
seem simple right now, but things can get tricky in more advanced situations
|
||||
@ -292,7 +292,7 @@ words, it looks like figure 4-2.
|
||||
Figure 4-2: Representation in memory of the binding `s2` that has a copy of
|
||||
`s1`'s pointer, length and capacity
|
||||
|
||||
And _not_ Figure 4-3, which is what memory would look like if Rust instead
|
||||
And *not* Figure 4-3, which is what memory would look like if Rust instead
|
||||
copied the heap data as well. If Rust did this, the operation `s2 = s1` could
|
||||
potentially be very expensive if the data on the heap was large.
|
||||
|
||||
@ -338,7 +338,7 @@ If you have heard the terms "shallow copy" and "deep copy" while working with
|
||||
other languages, the concept of copying the pointer, length, and capacity
|
||||
without copying the data probably sounds like a shallow copy. But because Rust
|
||||
also invalidates the first binding, instead of calling this a shallow copy,
|
||||
it's known as a _move_. Here we would read this by saying that `s1` was _moved_
|
||||
it's known as a *move*. Here we would read this by saying that `s1` was *moved*
|
||||
into `s2`. So what actually happens looks like Figure 4-4.
|
||||
|
||||
<img alt="s1 moved to s2" src="img/trpl04-04.svg" class="center" style="width: 50%;" />
|
||||
@ -349,12 +349,12 @@ That solves our problem! With only `s2` valid, when it goes out of scope, it
|
||||
alone will free the memory, and we’re done.
|
||||
|
||||
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.
|
||||
|
||||
#### Ways Bindings and Data Interact: Clone
|
||||
|
||||
If we _do_ want to deeply copy the `String`’s data and not just the `String`
|
||||
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 methods in
|
||||
the section on `structs` in Chapter XX, but they’re a
|
||||
common enough feature in many programming languages that you have probably seen
|
||||
@ -575,7 +575,7 @@ let s1 = String::from("hello");
|
||||
let len = calculate_length(&s1);
|
||||
```
|
||||
|
||||
The `&s1` syntax lets us create a reference which _refers_ to the value of `s1`
|
||||
The `&s1` syntax lets us create a reference which *refers* to the value of `s1`
|
||||
but does not own it. Because it does not own it, the value it points to will
|
||||
not be dropped when the reference goes out of scope.
|
||||
|
||||
@ -691,7 +691,7 @@ to track them down at runtime; Rust prevents this problem from happening since
|
||||
it won't even compile code with data races!
|
||||
|
||||
As always, we can use `{}`s to create a new scope, allowing for multiple mutable
|
||||
references, just not _simultaneous_ ones:
|
||||
references, just not *simultaneous* ones:
|
||||
|
||||
```rust
|
||||
let mut s = String::from("hello");
|
||||
@ -730,7 +730,7 @@ error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immuta
|
||||
| - immutable borrow ends here
|
||||
```
|
||||
|
||||
Whew! We _also_ cannot have a mutable reference while we have an immutable one.
|
||||
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
|
||||
from under them! Multiple immutable references are okay, however, since no one
|
||||
who is just reading the data has the ability to affect anyone else's reading of
|
||||
@ -823,7 +823,7 @@ This works, no problem. Ownership is moved out, nothing is deallocated.
|
||||
|
||||
Here’s a recap of what we’ve talked about:
|
||||
|
||||
1. At any given time, you may have _either_, but not both of:
|
||||
1. At any given time, you may have *either*, but not both of:
|
||||
1. One mutable reference.
|
||||
2. Any number of immutable references.
|
||||
2. References must always be valid.
|
||||
@ -849,7 +849,7 @@ fn first_word(s: &String) -> ?
|
||||
|
||||
This function, `first_word`, takes a `&String` as an argument. We don’t want
|
||||
ownership, so this is fine. But what should we return? We don’t really have a
|
||||
way to talk about _part_ of a string. We could return the index of the end of
|
||||
way to talk about *part* of a string. We could return the index of the end of
|
||||
the word, though. Let’s try that:
|
||||
|
||||
Filename: src/main.rs
|
||||
@ -940,7 +940,7 @@ function. Its signature would have to look like this:
|
||||
fn second_word(s: &String) -> (usize, usize) {
|
||||
```
|
||||
|
||||
Now we’re tracking both a start _and_ an ending index, and we have even more
|
||||
Now we’re tracking both a start *and* an ending index, and we have even more
|
||||
values that were calculated from data in a particular state but aren't tied to
|
||||
that state at all. We now have three unrelated variable bindings floating
|
||||
around which need to be kept in sync.
|
||||
|
@ -148,7 +148,7 @@ surprising side-effects on the dynamic execution semantics.
|
||||
|
||||
#### Assignment expressions
|
||||
|
||||
An _assignment expression_ consists of a pattern followed by an equals
|
||||
An *assignment expression* consists of a pattern followed by an equals
|
||||
sign (`=`) and an expression.
|
||||
|
||||
Evaluating an assignment expression either copies or
|
||||
|
@ -15,7 +15,7 @@ useful in a number of use cases that other languages aren’t good at: embedding
|
||||
in other languages, programs with specific space and time requirements, and
|
||||
writing low-level code, like device drivers and operating systems. It's also
|
||||
great for web applications: it powers the Rust package registry site, crates.io!
|
||||
We're excited to see what _you_ create with Rust.
|
||||
We're excited to see what *you* create with Rust.
|
||||
|
||||
This book is written for a reader who already knows how to program in at least
|
||||
one programming language. After reading this book, you should be comfortable
|
||||
|
@ -43,7 +43,7 @@ note: prior assignment occurs here
|
||||
|
||||
This is our first example of the compiler helping us find an error in our
|
||||
program! Compiler errors can be frustrating. Keep in mind that they only mean
|
||||
your program isn't safely doing what you want it to do yet; they do _not_ mean
|
||||
your program isn't safely doing what you want it to do yet; they do *not* mean
|
||||
that you're not a good programmer! Experienced Rustaceans still get compiler
|
||||
errors. The Rust compiler is trying to help your program be the very best.
|
||||
|
||||
@ -94,7 +94,7 @@ lead to bugs. If one part of our code operates on an assumption that a value
|
||||
will never change, and another part of our code changes that value, it's
|
||||
possible that the first part of the code won't do what it was designed to do.
|
||||
This cause of bugs can be difficult to track down after the fact, especially
|
||||
when the second piece of code only changes the value _sometimes_.
|
||||
when the second piece of code only changes the value *sometimes*.
|
||||
|
||||
In Rust, we can trust that a value we say won't change really won't change,
|
||||
because the compiler is enforcing that guarantee for us. When reading and
|
||||
|
@ -289,7 +289,7 @@ fn main() {
|
||||
|
||||
While arrays can be useful since they are a primitive type so using them can be
|
||||
very fast, they aren't as flexible as the vector type. The vector type is a
|
||||
similar collection type provided by the standard library that _is_ allowed to
|
||||
similar collection type provided by the standard library that *is* allowed to
|
||||
grow or shrink in size. If you're unsure whether to use an array or a vector,
|
||||
you should probably go with a vector, and we'll discuss them in more detail in
|
||||
Chapter 8.
|
||||
|
@ -30,7 +30,7 @@ body begins and ends.
|
||||
We can call any function we’ve defined by entering its name followed by a pair
|
||||
of parentheses. Since `another_function` is defined in the program, it can be
|
||||
called from inside the `main` function. Note that we defined
|
||||
`another_function` _after_ the `main` function in our source code; we could
|
||||
`another_function` *after* the `main` function in our source code; we could
|
||||
have defined it before as well. Rust doesn’t care where you define your
|
||||
functions, only that they are defined somewhere.
|
||||
|
||||
@ -81,7 +81,7 @@ specify the type of `x` as `i32`. When we pass `5` to `another_function`,
|
||||
the `println!` macro puts `5` where the pair of curly braces were in the format
|
||||
string.
|
||||
|
||||
In function signatures, we _must_ declare the type. This is a deliberate
|
||||
In function signatures, we *must* declare the type. This is a deliberate
|
||||
decision in the design of Rust; requiring type annotations in function
|
||||
definitions means the compiler almost never needs you to use them elsewhere in
|
||||
the code in order to figure out what you mean.
|
||||
|
@ -64,7 +64,7 @@ $ cargo run
|
||||
condition was false
|
||||
```
|
||||
|
||||
It’s also worth noting that the condition here _must_ be a `bool`. To see what
|
||||
It’s also worth noting that the condition here *must* be a `bool`. To see what
|
||||
happens if the condition isn't a `bool`, try running this code:
|
||||
|
||||
Filename: src/main.rs
|
||||
@ -439,5 +439,5 @@ programs to do things like:
|
||||
* Print the lyrics to the Christmas carol *The Twelve Days of Christmas*,
|
||||
taking advantage of the repetition in the song.
|
||||
|
||||
When you're ready to move on, we'll talk about a concept in Rust that _doesn't_
|
||||
When you're ready to move on, we'll talk about a concept in Rust that *doesn't*
|
||||
commonly exist in other programming languages: ownership.
|
||||
|
@ -104,7 +104,7 @@ let s = "hello";
|
||||
|
||||
The variable `s` refers to a string literal, where the value of the
|
||||
string is hard coded into the text of our program. The variable is valid from
|
||||
the point at which it’s declared until the end of the current _scope_. That is:
|
||||
the point at which it’s declared until the end of the current *scope*. That is:
|
||||
|
||||
```rust
|
||||
{ // s is not valid here, it’s not yet declared
|
||||
@ -220,7 +220,7 @@ return the memory. Rust calls `drop` automatically at the closing `}`.
|
||||
> Initialization* in C++, or RAII for short. While they are very similar,
|
||||
> Rust’s take on this concept has a number of differences, so we don’t tend
|
||||
> to use the same term. If you’re familiar with this idea, keep in mind that it
|
||||
> is _roughly_ similar in Rust, but not identical.
|
||||
> is *roughly* similar in Rust, but not identical.
|
||||
|
||||
This pattern has a profound impact on the way that Rust code is written. It may
|
||||
seem simple right now, but things can get tricky in more advanced situations
|
||||
@ -281,7 +281,7 @@ words, it looks like figure 4-2.
|
||||
Figure 4-2: Representation in memory of the variable `s2` that has a copy of
|
||||
`s1`'s pointer, length and capacity
|
||||
|
||||
And _not_ Figure 4-3, which is what memory would look like if Rust instead
|
||||
And *not* Figure 4-3, which is what memory would look like if Rust instead
|
||||
copied the heap data as well. If Rust did this, the operation `s2 = s1` could
|
||||
potentially be very expensive if the data on the heap was large.
|
||||
|
||||
@ -327,7 +327,7 @@ If you have heard the terms "shallow copy" and "deep copy" while working with
|
||||
other languages, the concept of copying the pointer, length, and capacity
|
||||
without copying the data probably sounds like a shallow copy. But because Rust
|
||||
also invalidates the first variable, instead of calling this a shallow copy,
|
||||
it's known as a _move_. Here we would read this by saying that `s1` was _moved_
|
||||
it's known as a *move*. Here we would read this by saying that `s1` was *moved*
|
||||
into `s2`. So what actually happens looks like Figure 4-4.
|
||||
|
||||
<img alt="s1 moved to s2" src="img/trpl04-04.svg" class="center" style="width: 50%;" />
|
||||
@ -338,12 +338,12 @@ That solves our problem! With only `s2` valid, when it goes out of scope, it
|
||||
alone will free the memory, and we’re done.
|
||||
|
||||
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.
|
||||
|
||||
#### Ways Variables and Data Interact: Clone
|
||||
|
||||
If we _do_ want to deeply copy the `String`’s data and not just the `String`
|
||||
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 methods in
|
||||
the section on [`structs` in Chapter XX][structs]<!-- ignore -->, but they’re a
|
||||
common enough feature in many programming languages that you have probably seen
|
||||
|
@ -48,7 +48,7 @@ let s1 = String::from("hello");
|
||||
let len = calculate_length(&s1);
|
||||
```
|
||||
|
||||
The `&s1` syntax lets us create a reference which _refers_ to the value of `s1`
|
||||
The `&s1` syntax lets us create a reference which *refers* to the value of `s1`
|
||||
but does not own it. Because it does not own it, the value it points to will
|
||||
not be dropped when the reference goes out of scope.
|
||||
|
||||
@ -162,7 +162,7 @@ to track them down at runtime; Rust prevents this problem from happening since
|
||||
it won't even compile code with data races!
|
||||
|
||||
As always, we can use `{}`s to create a new scope, allowing for multiple mutable
|
||||
references, just not _simultaneous_ ones:
|
||||
references, just not *simultaneous* ones:
|
||||
|
||||
```rust
|
||||
let mut s = String::from("hello");
|
||||
@ -201,7 +201,7 @@ error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immuta
|
||||
| - immutable borrow ends here
|
||||
```
|
||||
|
||||
Whew! We _also_ cannot have a mutable reference while we have an immutable one.
|
||||
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
|
||||
from under them! Multiple immutable references are okay, however, since no one
|
||||
who is just reading the data has the ability to affect anyone else's reading of
|
||||
@ -294,7 +294,7 @@ This works, no problem. Ownership is moved out, nothing is deallocated.
|
||||
|
||||
Here’s a recap of what we’ve talked about:
|
||||
|
||||
1. At any given time, you may have _either_, but not both of:
|
||||
1. At any given time, you may have *either*, but not both of:
|
||||
1. One mutable reference.
|
||||
2. Any number of immutable references.
|
||||
2. References must always be valid.
|
||||
|
@ -17,7 +17,7 @@ fn first_word(s: &String) -> ?
|
||||
|
||||
This function, `first_word`, takes a `&String` as an argument. We don’t want
|
||||
ownership, so this is fine. But what should we return? We don’t really have a
|
||||
way to talk about _part_ of a string. We could return the index of the end of
|
||||
way to talk about *part* of a string. We could return the index of the end of
|
||||
the word, though. Let’s try that:
|
||||
|
||||
Filename: src/main.rs
|
||||
@ -120,7 +120,7 @@ function. Its signature would have to look like this:
|
||||
fn second_word(s: &String) -> (usize, usize) {
|
||||
```
|
||||
|
||||
Now we’re tracking both a start _and_ an ending index, and we have even more
|
||||
Now we’re tracking both a start *and* an ending index, and we have even more
|
||||
values that were calculated from data in a particular state but aren't tied to
|
||||
that state at all. We now have three unrelated variables floating
|
||||
around which need to be kept in sync.
|
||||
|
@ -134,7 +134,7 @@ the safety of Rust code.
|
||||
`None`'s type is `Option<T>`. I hope with the clarifications I added in the
|
||||
previous section that this will be clear by this point. /Carol -->
|
||||
|
||||
So, how _do_ you get the `T` value out of a `Some` variant when you have a
|
||||
So, how *do* you get the `T` value out of a `Some` variant when you have a
|
||||
value of type `Option<T>` so that you can use that value? The `Option<T>` enum
|
||||
has a large number of methods useful in a variety of situations that you can
|
||||
check out in [its documentation][docs]<!-- ignore -->, and becoming familiar
|
||||
@ -144,8 +144,8 @@ with them will be extremely useful in your journey with Rust.
|
||||
|
||||
What we generally want to do in order to use an `Option<T>` value is to have
|
||||
code that will handle each variant. We want some code that will run only in the
|
||||
case that we have a `Some(T)` value, and this code _is_ allowed to use the
|
||||
inner `T`. We want some _other_ code to run if we have a `None` value, and that
|
||||
case that we have a `Some(T)` value, and this code *is* allowed to use the
|
||||
inner `T`. We want some *other* code to run if we have a `None` value, and that
|
||||
code doesn't have a `T` value available. The `match` expression is a control
|
||||
flow construct that does just this, when used with enums: it will run different
|
||||
code depending on which variant of the enum it has, and that code can use the
|
||||
|
@ -168,7 +168,7 @@ fn connect() {
|
||||
|
||||
Note that we don't need a `mod` declaration in this file. `mod` is for
|
||||
declaring a new module, and we've already declared this module in `src/lib.rs`.
|
||||
This file provides the _contents_ of the `client` module. If we put a `mod
|
||||
This file provides the *contents* of the `client` module. If we put a `mod
|
||||
client` here, we'd be giving the `client` module its own submodule named
|
||||
`client`!
|
||||
|
||||
@ -285,7 +285,7 @@ valid, but then which module would the files `src/client.rs` and
|
||||
`src/server.rs`, respectively, be for?
|
||||
|
||||
Instead of continuing to follow the same file naming pattern we used
|
||||
previously, we can do what the error suggests. We'll make a new _directory_,
|
||||
previously, we can do what the error suggests. We'll make a new *directory*,
|
||||
move `src/server.rs` into it, and change `src/network.rs` to
|
||||
`src/network/mod.rs`. Then, when we try to build:
|
||||
|
||||
|
@ -292,7 +292,7 @@ we cannot directly do this.
|
||||
### Slicing Strings
|
||||
|
||||
However, indexing the bytes of a string is very useful, and is not expected to
|
||||
be fast. While we can't use `[]` with a single number, we _can_ use `[]` with
|
||||
be fast. While we can't use `[]` with a single number, we *can* use `[]` with
|
||||
a range to create a string slice from particular bytes:
|
||||
|
||||
```rust
|
||||
|
@ -88,7 +88,7 @@ statement with a type annotation:
|
||||
let PATTERN: TYPE = VALUE;
|
||||
```
|
||||
|
||||
Note that the colon and the `TYPE` go _after_ the `PATTERN`, not in the pattern
|
||||
Note that the colon and the `TYPE` go *after* the `PATTERN`, not in the pattern
|
||||
itself. As an example, here’s our more complex pattern with two variables:
|
||||
|
||||
```rust
|
||||
|
Loading…
Reference in New Issue
Block a user