Remove 'variable binding' concept.

This commit is contained in:
Elahn Ientile 2016-10-06 11:21:50 +10:00
parent 22f457c07e
commit 65f12cf6a4
6 changed files with 21 additions and 37 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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, lets 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

View File

@ -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.

View File

@ -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.
Lets try a more complex pattern. Change our example program to this:
@ -53,8 +51,8 @@ And heres 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