mirror of
https://github.com/rust-lang-cn/book-cn.git
synced 2025-02-03 07:48:41 +08:00
Remove 'variable binding' concept.
This commit is contained in:
parent
22f457c07e
commit
65f12cf6a4
@ -136,20 +136,6 @@ variables. In cases where you're using large data structures, mutating an
|
||||
instance in place may be faster than copying and returning newly allocated
|
||||
instances. It all depends on the tradeoffs you want to make in your situation.
|
||||
|
||||
### Variable Binding and Constants
|
||||
|
||||
In rust we talk about binding a variable name to a value, which simply means
|
||||
initializing a variable with a value, also known as initial assignment.
|
||||
|
||||
```rust,ignore
|
||||
let x; // declares a variable x, which is not yet bound
|
||||
let x = 37; // declares a variable x, which is bound to the value 37
|
||||
const x: i32 = 37; // declares a constant x, whose value is 37
|
||||
```
|
||||
|
||||
A constant is declared using `const`, is bound to a value at compile time and
|
||||
remains unchanged throughout the execution of the program.
|
||||
|
||||
### Shadowing
|
||||
|
||||
As we saw in the guessing game tutorial, we can declare new variables with the
|
||||
@ -173,7 +159,7 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
This program first binds `x` to a value of `5`. Then, it shadows `x` by
|
||||
This program first initializes `x` to a value of `5`. Then, it shadows `x` by
|
||||
repeating `let x =`, taking the original value and adding `1` so that the value
|
||||
of `x` is then `6`. The third `let` statement also shadows `x`, taking the
|
||||
previous value and multiplying it by `2` to give `x` a final value of `12`. If
|
||||
@ -193,7 +179,7 @@ have the variable be immutable after those transformations have been completed.
|
||||
|
||||
The other difference between `mut` and shadowing is that, since we're
|
||||
effectively creating a new variable when we use the `let` keyword again, we can
|
||||
change the type of the value we're binding to, but reuse the same name. For
|
||||
change the type of the value, but reuse the same name. For
|
||||
example, say we ask a user to show us how many spaces they want between some
|
||||
text by sending us space characters, but we really want to store that as a
|
||||
number:
|
||||
@ -230,4 +216,4 @@ error: aborting due to previous error
|
||||
```
|
||||
|
||||
Now that we've explored how variables work, let's look at some more
|
||||
data types of values that we can bind variables to.
|
||||
data types they can have.
|
||||
|
@ -222,8 +222,8 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
Note that the single name `tup` binds to the entire tuple, emphasizing the fact
|
||||
that a tuple is considered a single compound element. To get the individual
|
||||
The variable `tup` contains the entire tuple,
|
||||
it's a single compound element. To get the individual
|
||||
values out of a tuple, we can use pattern matching to destructure a tuple
|
||||
value, like this:
|
||||
|
||||
@ -239,7 +239,7 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
In this program, we first create a tuple and bind it to the name `tup`. We then
|
||||
In this program, we first create a tuple and assign it to the variable `tup`. We then
|
||||
use a pattern with `let` to take `tup` and turn it into three separate
|
||||
variables, `x`, `y`, and `z`. This is called *destructuring*, because it breaks
|
||||
the single tuple into three parts. Finally, we print the value of `y`, which is
|
||||
@ -271,7 +271,7 @@ tuple is 0.
|
||||
|
||||
### Arrays
|
||||
|
||||
Another way to bind a name to a collection of multiple values is with an
|
||||
Another way to have a collection of multiple values is with an
|
||||
*array*. Unlike a tuple, every element of an array must have the same type.
|
||||
Arrays in Rust are different than arrays in some other languages because arrays
|
||||
in Rust have a fixed length: once declared, they cannot grow or shrink in size.
|
||||
|
@ -178,7 +178,7 @@ error: Could not compile `functions`.
|
||||
```
|
||||
|
||||
The `let y = 6` statement does not return a value, so there isn't anything for
|
||||
`x` to bind to. This is different than in other languages like C and Ruby where
|
||||
`x` to initialize to. This is different than in other languages like C and Ruby where
|
||||
the assignment returns the value of the assignment. In those languages, we can
|
||||
write `x = y = 6` and have both `x` and `y` have the value `6`; that is not the
|
||||
case in Rust.
|
||||
|
@ -238,8 +238,8 @@ let y = x;
|
||||
```
|
||||
|
||||
We can probably guess what this is doing based on our experience with other
|
||||
languages: “Bind the value `5` to `x`, then make a copy of the value in `x` and
|
||||
bind it to `y`.” We now have two variables, `x` and `y`, and both equal `5`.
|
||||
languages: “Assign the value `5` to `x`, then make a copy of the value in `x` and
|
||||
assign it to `y`.” We now have two variables, `x` and `y`, and both equal `5`.
|
||||
This is indeed what is happening since integers are simple values with a known,
|
||||
fixed size, and these two `5` values are pushed onto the stack.
|
||||
|
||||
@ -252,7 +252,7 @@ let s2 = s1;
|
||||
|
||||
This looks very similar to the previous code, so we might assume that the way
|
||||
it works would be the same: that the second line would make a copy of the value
|
||||
in `s1` and bind it to `s2`. This isn't quite what happens.
|
||||
in `s1` and assign it to `s2`. This isn't quite what happens.
|
||||
|
||||
To explain this more thoroughly, let’s take a look at what `String` looks like
|
||||
under the covers in Figure 4-1. A `String` is made up of three parts, shown on
|
||||
|
@ -193,7 +193,7 @@ Some(i) => Some(i + 1),
|
||||
```
|
||||
|
||||
Does `Some(5)` match `Some(i)`? Why yes it does! We have the same variant. The
|
||||
`i` binds to the value inside of the `Some`, so `i` has the value `5`. Then we
|
||||
`i` initializes to the value inside of the `Some`, so `i` has the value `5`. Then we
|
||||
execute the code in that match arm: take `i`, which is `5`, add one to it, and
|
||||
create a new `Some` value with our total inside.
|
||||
|
||||
@ -209,7 +209,7 @@ return the `None` value that is on the right side of the `=>`. We don't
|
||||
check any other arms since we found one that matched.
|
||||
|
||||
Combining `match` and enums together is extremely powerful. You'll see this
|
||||
pattern a lot in Rust code: `match` against an enum, bind to the data
|
||||
pattern a lot in Rust code: `match` against an enum, initialize a variable to the data
|
||||
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
|
||||
it. It's consistently a user favorite.
|
||||
|
@ -13,10 +13,8 @@ A basic `let` statement has this form:
|
||||
let PATTERN = EXPRESSION;
|
||||
```
|
||||
|
||||
We've seen statements like `let x = 5;` with a variable name in the `PATTERN`
|
||||
slot; a variable name is just a particularly humble form of pattern.
|
||||
|
||||
## Binding Multiple variables
|
||||
We've seen statements like `let x = 5;` with a variable in the `PATTERN`
|
||||
slot; a variable is just a particularly humble form of pattern.
|
||||
|
||||
Let’s try a more complex pattern. Change our example program to this:
|
||||
|
||||
@ -53,8 +51,8 @@ And here’s the value:
|
||||
(5, 6)
|
||||
```
|
||||
|
||||
As you can see, the two line up visually, and so `let` binds `5` to `x` and `6`
|
||||
to `y`. We could have used two `let` statements as well:
|
||||
As you can see, the two line up visually, and so `let` initializes `x` to `5`
|
||||
and `y` to `6`. We could have used two `let` statements as well:
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
@ -133,7 +131,7 @@ This prints `one or two`.
|
||||
|
||||
## ref and ref mut
|
||||
|
||||
Usually, when you match against a pattern, variables are bound by value.
|
||||
Usually, when you match against a pattern, variables are initialized to a value.
|
||||
This means you'll end up moving the value out:
|
||||
|
||||
```rust,ignore
|
||||
@ -148,7 +146,7 @@ match name {
|
||||
println!("name is: {:?}", name);
|
||||
```
|
||||
|
||||
If you'd prefer to bind `name` by reference, use the `ref` keyword:
|
||||
If you'd prefer to initialize `name` to a reference, use the `ref` keyword:
|
||||
|
||||
```rust
|
||||
let name = Some(String::from("Bors"));
|
||||
@ -206,13 +204,13 @@ struct Point {
|
||||
let origin = Point { x: 0, y: 0 };
|
||||
|
||||
match origin {
|
||||
Point { x, y } => { }, // x and y are bound here
|
||||
Point { x, y } => { }, // x and y are initialized here
|
||||
}
|
||||
```
|
||||
|
||||
## Shadowing
|
||||
|
||||
As with all variables, anything bound by a pattern will shadow variables
|
||||
As with all variables, those declared by a pattern will shadow variables
|
||||
outside of the `match` construct:
|
||||
|
||||
```rust
|
||||
|
Loading…
Reference in New Issue
Block a user