From 64f4021c408898b961341e1ecadc4d155dfe6b8e Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 10 Apr 2015 11:50:28 -0400 Subject: [PATCH] copy-editing: if I decided to break if-let out, as it's too complex for this part, but moving if that late seems silly too. --- src/doc/trpl/SUMMARY.md | 1 + src/doc/trpl/if-let.md | 3 ++ src/doc/trpl/if.md | 106 +++++----------------------------------- 3 files changed, 15 insertions(+), 95 deletions(-) create mode 100644 src/doc/trpl/if-let.md diff --git a/src/doc/trpl/SUMMARY.md b/src/doc/trpl/SUMMARY.md index e4c2ffac51a..29210fa6c16 100644 --- a/src/doc/trpl/SUMMARY.md +++ b/src/doc/trpl/SUMMARY.md @@ -41,6 +41,7 @@ * [Traits](traits.md) * [Operators and Overloading](operators-and-overloading.md) * [Generics](generics.md) + * [if let](if-let.md) * [Trait Objects](trait-objects.md) * [Closures](closures.md) * [Universal Function Call Syntax](ufcs.md) diff --git a/src/doc/trpl/if-let.md b/src/doc/trpl/if-let.md new file mode 100644 index 00000000000..9e010b020c1 --- /dev/null +++ b/src/doc/trpl/if-let.md @@ -0,0 +1,3 @@ +% if let + +COMING SOON diff --git a/src/doc/trpl/if.md b/src/doc/trpl/if.md index 4b0058e78df..a532dabf8d1 100644 --- a/src/doc/trpl/if.md +++ b/src/doc/trpl/if.md @@ -1,10 +1,10 @@ % if -Rust's take on `if` is not particularly complex, but it's much more like the -`if` you'll find in a dynamically typed language than in a more traditional -systems language. So let's talk about it, to make sure you grasp the nuances. +Rust’s take on `if` is not particularly complex, but it’s much more like the +`if` you’ll find in a dynamically typed language than in a more traditional +systems language. So let’s talk about it, to make sure you grasp the nuances. -`if` is a specific form of a more general concept, the *branch*. The name comes +`if` is a specific form of a more general concept, the ‘branch’. The name comes from a branch in a tree: a decision point, where depending on a choice, multiple paths can be taken. @@ -20,11 +20,11 @@ if x == 5 { If we changed the value of `x` to something else, this line would not print. More specifically, if the expression after the `if` evaluates to `true`, then -the block is executed. If it's `false`, then it is not. +the block is executed. If it’s `false`, then it is not. If you want something to happen in the `false` case, use an `else`: -```{rust} +```rust let x = 5; if x == 5 { @@ -50,8 +50,7 @@ if x == 5 { This is all pretty standard. However, you can also do this: - -```{rust} +```rust let x = 5; let y = if x == 5 { @@ -63,95 +62,12 @@ let y = if x == 5 { Which we can (and probably should) write like this: -```{rust} +```rust let x = 5; let y = if x == 5 { 10 } else { 15 }; // y: i32 ``` -This reveals two interesting things about Rust: it is an expression-based -language, and semicolons are different from semicolons in other 'curly brace -and semicolon'-based languages. These two things are related. - -## Expressions vs. Statements - -Rust is primarily an expression based language. There are only two kinds of -statements, and everything else is an expression. - -So what's the difference? Expressions return a value, and statements do not. -In many languages, `if` is a statement, and therefore, `let x = if ...` would -make no sense. But in Rust, `if` is an expression, which means that it returns -a value. We can then use this value to initialize the binding. - -Speaking of which, bindings are a kind of the first of Rust's two statements. -The proper name is a *declaration statement*. So far, `let` is the only kind -of declaration statement we've seen. Let's talk about that some more. - -In some languages, variable bindings can be written as expressions, not just -statements. Like Ruby: - -```{ruby} -x = y = 5 -``` - -In Rust, however, using `let` to introduce a binding is _not_ an expression. The -following will produce a compile-time error: - -```{ignore} -let x = (let y = 5); // expected identifier, found keyword `let` -``` - -The compiler is telling us here that it was expecting to see the beginning of -an expression, and a `let` can only begin a statement, not an expression. - -Note that assigning to an already-bound variable (e.g. `y = 5`) is still an -expression, although its value is not particularly useful. Unlike C, where an -assignment evaluates to the assigned value (e.g. `5` in the previous example), -in Rust the value of an assignment is the unit type `()` (which we'll cover later). - -The second kind of statement in Rust is the *expression statement*. Its -purpose is to turn any expression into a statement. In practical terms, Rust's -grammar expects statements to follow other statements. This means that you use -semicolons to separate expressions from each other. This means that Rust -looks a lot like most other languages that require you to use semicolons -at the end of every line, and you will see semicolons at the end of almost -every line of Rust code you see. - -What is this exception that makes us say "almost"? You saw it already, in this -code: - -```{rust} -let x = 5; - -let y: i32 = if x == 5 { 10 } else { 15 }; -``` - -Note that I've added the type annotation to `y`, to specify explicitly that I -want `y` to be an integer. - -This is not the same as this, which won't compile: - -```{ignore} -let x = 5; - -let y: i32 = if x == 5 { 10; } else { 15; }; -``` - -Note the semicolons after the 10 and 15. Rust will give us the following error: - -```text -error: mismatched types: expected `i32`, found `()` (expected i32, found ()) -``` - -We expected an integer, but we got `()`. `()` is pronounced *unit*, and is a -special type in Rust's type system. In Rust, `()` is _not_ a valid value for a -variable of type `i32`. It's only a valid value for variables of the type `()`, -which aren't very useful. Remember how we said statements don't return a value? -Well, that's the purpose of unit in this case. The semicolon turns any -expression into a statement by throwing away its value and returning unit -instead. - -There's one more time in which you won't see a semicolon at the end of a line -of Rust code. For that, we'll need our next concept: functions. - -TODO: `if let` +This works because `if` is an expression. The value of the expression is the +value of the last expression in whichever branch was chosen. An `if` without an +`else` always results in `()` as the value.