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 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. 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 ### Shadowing
As we saw in the guessing game tutorial, we can declare new variables with the 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 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 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 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 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 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 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 text by sending us space characters, but we really want to store that as a
number: 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 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 The variable `tup` contains the entire tuple,
that a tuple is considered a single compound element. To get the individual it's a single compound element. To get the individual
values out of a tuple, we can use pattern matching to destructure a tuple values out of a tuple, we can use pattern matching to destructure a tuple
value, like this: 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 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 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 the single tuple into three parts. Finally, we print the value of `y`, which is
@ -271,7 +271,7 @@ tuple is 0.
### Arrays ### 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. *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 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. 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 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 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 write `x = y = 6` and have both `x` and `y` have the value `6`; that is not the
case in Rust. 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 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 languages: “Assign 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`. 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, 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. 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 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 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 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 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 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 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. 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. check any other arms since we found one that matched.
Combining `match` and enums together is extremely powerful. You'll see this 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 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.

View File

@ -13,10 +13,8 @@ A basic `let` statement has this form:
let PATTERN = EXPRESSION; let PATTERN = EXPRESSION;
``` ```
We've seen statements like `let x = 5;` with a variable name in the `PATTERN` We've seen statements like `let x = 5;` with a variable in the `PATTERN`
slot; a variable name is just a particularly humble form of pattern. slot; a variable is just a particularly humble form of pattern.
## Binding Multiple variables
Lets try a more complex pattern. Change our example program to this: Lets try a more complex pattern. Change our example program to this:
@ -53,8 +51,8 @@ And heres the value:
(5, 6) (5, 6)
``` ```
As you can see, the two line up visually, and so `let` binds `5` to `x` and `6` As you can see, the two line up visually, and so `let` initializes `x` to `5`
to `y`. We could have used two `let` statements as well: and `y` to `6`. We could have used two `let` statements as well:
```rust ```rust
fn main() { fn main() {
@ -133,7 +131,7 @@ This prints `one or two`.
## ref and ref mut ## 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: This means you'll end up moving the value out:
```rust,ignore ```rust,ignore
@ -148,7 +146,7 @@ match name {
println!("name is: {:?}", 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 ```rust
let name = Some(String::from("Bors")); let name = Some(String::from("Bors"));
@ -206,13 +204,13 @@ struct Point {
let origin = Point { x: 0, y: 0 }; let origin = Point { x: 0, y: 0 };
match origin { match origin {
Point { x, y } => { }, // x and y are bound here Point { x, y } => { }, // x and y are initialized here
} }
``` ```
## Shadowing ## 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: outside of the `match` construct:
```rust ```rust