Rust by Example - страница 23

стр.

Would you like a challenge? Fix the following example to use if let:

>// This enum purposely neither implements nor derives PartialEq.

>// That is why comparing Foo::Bar == a fails below.

>enum Foo {Bar}

>fn main() {

>let a = Foo::Bar;

>// Variable a matches Foo::Bar

>if Foo::Bar == a {

>// ^-- this causes a compile-time error. Use `if let` instead.

>println!("a is foobar");

>}

>}

>הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Similar to if let, while let can make awkward match sequences more tolerable. Consider the following sequence that increments i:


>#![allow(unused)]

>fn main() {

>// Make `optional` of type `Option`

>let mut optional = Some(0);


>// Repeatedly try this test.

>loop {

>match optional {

>// If `optional` destructures, evaluate the block.

>Some(i) => {

>if i > 9 {

>println!("Greater than 9, quit!");

>optional = None;

>} else {

>println!("`i` is `{:?}`. Try again.", i);

>optional = Some(i + 1);

>}

>// ^ Requires 3 indentations!

>},

>// Quit the loop when the destructure fails:

>_ => { break; }

>// ^ Why should this be required? There must be a better way!

>}

>}

>}

Using while let makes this sequence much nicer:

>fn main() {

>// Make `optional` of type `Option`

>let mut optional = Some(0);

>// This reads: "while `let` destructures `optional` into

>// `Some(i)`, evaluate the block (`{}`). Else `break`.

>while let Some(i) = optional {

>if i > 9 {

>println!("Greater than 9, quit!");

>optional = None;

>} else {

>println!("`i` is `{:?}`. Try again.", i);

>optional = Some(i + 1);

>}

>// ^ Less rightward drift and doesn't require

>// explicitly handling the failing case.

>}

>// ^ `if let` had additional optional `else`/`else if`

>// clauses. `while let` does not have these.

>}

>הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Functions are declared using the fn keyword. Its arguments are type annotated, just like variables, and, if the function returns a value, the return type must be specified after an arrow ->.

The final expression in the function will be used as return value. Alternatively, the return statement can be used to return a value earlier from within the function, even from inside loops or if statements.

Let's rewrite FizzBuzz using functions!

>// Unlike C/C++, there's no restriction on the order of function definitions

>fn main() {

>// We can use this function here, and define it somewhere later

>fizzbuzz_to(100);

>}

>// Function that returns a boolean value

>fn is_divisible_by(lhs: u32, rhs: u32) -> bool {

>// Corner case, early return

>if rhs == 0 {

>return false;

>}

>// This is an expression, the `return` keyword is not necessary here

>lhs % rhs == 0

>}

>// Functions that "don't" return a value, actually return the unit type `()`

>fn fizzbuzz(n: u32) -> () {

>if is_divisible_by(n, 15) {

>println!("fizzbuzz");

>} else if is_divisible_by(n, 3) {

>println!("fizz");

>} else if is_divisible_by(n, 5) {

>println!("buzz");

>} else {

>println!("{}", n);

>}

>}

>// When a function returns `()`, the return type can be omitted from the

>// signature

>fn fizzbuzz_to(n: u32) {

>for n in 1..n + 1 {

>fizzbuzz(n);

>}

>}

>הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה