📜 ⬆️ ⬇️

Rust on examples. Part 2

This is the second part of a series of articles on translating the book “Rust by Example”. The first part can be read here .

Continue?

Content


  1. Expressions
  2. Branch operators
  3. Hinges
  4. While loop
  5. For loop and range function
  6. Functions

1. Expressions


In Rust, almost any statement (statement) is also an expression, which means that they can return some kind of result. This behavior is not always necessary to add nothing to add ; In the end.

The expressions in the block can be used as r-values ​​of values, and the latter will be assigned as l-value .
* What is Rvalue and Lvalue read here .
')
But, if the last expression in the block will be injected with a semicolon, the result will be equal to the empty tuple: () .

fn main() { let x = 5u; let y = { let x_squared = x * x; let x_cube = x_squared * x; // `y`    x_cube + x_squared + x }; let z = { //       ,    // ,    `z`   `()` 2 * x; }; println!("x is {}", x); println!("y is {}", y); println!("z is {}", z); } 

2. Branch operators


The if-else is C-like. Unlike C, the logical condition should not be enclosed in parentheses, and curly braces are required after each condition.

if-else is also an expression; and, due to the type safety of Rust, all branches must return a value of the same type.

 fn main() { let n = 5i; if n < 0 { print!("{} is negative", n); } else if n > 0 { print!("{} is positive", n); } else { print!("{} is zero", n); } let big_n = if n < 10 && n > -10 { println!(", and is a small number, increase ten-fold"); //    `int` 10 * n } else { println!(", and is a big number, reduce by two"); //     `int` n / 2 // ^      }; println!("{} -> {}", n, big_n); } 

3. Loops


The loop keyword in Rust creates an infinite loop (loop).

The break statement allows you to exit the loop at any time, and continue skips the rest of the iteration and starts execution again.

 fn main() { let mut count = 0u; println!("Let's count until infinity!"); //   loop { count += 1; if count == 3 { println!("three"); //      continue; } println!("{}", count); if count == 5 { println!("OK, that's enough"); //     break; } } } 

3.1 Nesting and Labels

Loops can be nested. In such cases, they should contain the label 'label , and break/continue statements should be written with this label.

 fn main() { 'outer: loop { println!("Entered the outer loop"); 'inner: loop { println!("Entered the inner loop"); //     //break; //     break 'outer; } println!("This point will never be reached"); } println!("Exited the outer loop"); } 

4. while loop


The body of the loop will be executed as long as the condition in while is true.

Let's write fizzbuzz using a while .

 fn main() { //    let mut n = 1u; //   `n`  101 while n < 101 { if n % 15 == 0 { println!("fizzbuzz"); } else if n % 3 == 0 { println!("fizz"); } else if n % 5 == 0 { println!("buzz"); } else { println!("{}", n); } //   n += 1; } } 

5. The for loop and the range function


The for in construct can be used to iterate over Iterator and a lazy generator (more later). The range function is one of the most common iterators. range(a, b) will produce values ​​from a to b-1 by changing the step by one.

Let's write fizzbuzz using for instead of while .

 fn main() { // `n`   : 1, 2, ..., 100    for n in range(1u, 101) { if n % 15 == 0 { println!("fizzbuzz"); } else if n % 3 == 0 { println!("fizz"); } else if n % 5 == 0 { println!("buzz"); } else { println!("{}", n); } } } 

6. Functions


Functions are declared using the fn keyword. Arguments are annotated with types, like variables; and, if the function returns a value, the return type must be specified after the arrow -> .

The last expression in the function body will be used as a return value, or you can use the return operator to return the value early from the function, even from an internal loop or conditional operator.

Rewrite fizzbuzz using functions!

 // ,     fn is_divisible_by(lhs: uint, rhs: uint) -> bool { //   ,     if rhs == 0 { return false; } //  ,     `return`    lhs % rhs == 0 } // ,    ,      `()` fn fizzbuzz(n: uint) -> () { 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); } } //    `()`,     fn fizzbuzz_to(n: uint) { for n in range(1, n + 1) { fizzbuzz(n); } } fn main() { fizzbuzz_to(100); } 

6.1 Unused functions

The compiler provides dead_code lint to warn about unused functions. You can add the #[allow(dead_code)] attribute to disable the notification.

 fn used_function() {} // `#[allow(dead_code)]`  ,    `dead_code` #[allow(dead_code)] fn unused_function() {} fn noisy_unused_function() {} //  ^  ,    fn main() { used_function(); } 

Note that in real programs, you must eliminate the "dead code". In these examples we use it for demonstration.

Conclusion


Join google-group: Rust in Russian for more information on this language.
You can help with the translation on Github: github.com/eg0r/rust-by-example

Send all comments, errors or inaccuracies to me in the mail.

Source: https://habr.com/ru/post/233621/


All Articles