Process control statements in Rust are called process control expressions.

Conditional expression

An expression must have one, so branches of an if expression must return a value of the same type. This is why Rust has no ternary operators. If expressions are evaluated in the same way as block expressions.

fn main () { let n = 13; let big_n = if (n < 10 && n > -10) { 10 * n } else { n / 2 } assert_eq! (big_n, 6) }Copy the code

In the code above, assignment of big_n is done by an if expression. I’m going to calculate the size of the n interval to determine the final value. Because n is 13, Rust will infer that it is of type I32, even though the type is not explicitly specified. In the if conditional branch, the product of n is bound to be an integer. Rust has inferred big_n to be of type I32, so when calculating n divided by 2, the Rust compiler intercepts the result by removing the decimal point. The final result is 6

Loop expression

There are three types of loop expressions in Rust: while, loop, and for… The in expression is used in the same way as other languages

fn main () { for n in 1.. 101 {/ / 1.. Range 0 to 101 if n % 15 == 0 {println! ("fizzbuzz"); } else if n % 3 === 0 { println! ("fizz"); } else if n % 5 == 0 { println! ("buzz"); } else { println! ("{}", n); }}}Copy the code

for … The in expression is an iterator in which 1.. 101 is a Range type and is an iterator. When using infinite loops, always use loops instead of while True.

fn while_true (x: i32) -> i32 { while true { return x + 1; } fn main () {let y = while_true(5); assert_eq! (y, 6) }Copy the code

The while_true module returns the unit value, while while_true returns i32, so it does not match. This is because when the Rust compiler does Flow Sensitive analysis of a while loop, it does not check for conditions. The compiler considers while conditions to be true or false, so expressions inside the loop are ignored. At this point, the compiler only knows that the while true loop returns the unit value and the function returns i32, so it throws an error. All this is due to the limitations of the CTFE function. The while condition expression cannot be used as a compiler constant.

Match expressions and matching patterns

Rust provides match expressions

fn main () { let number = 42; match number { 0 => println! ("Origin"), 1... 3 => println! ("All"), | 5 | 7 | 13 => println! ("Bad Luck"), n @ 42 => println! ("Answer is {}", n), _ => println! ("Common") } }Copy the code

Match is used to Match various situations, similar to a Switch case statement

The Match branch uses the Pattern Matching technology. Pattern matching occurs in data structure strings, such as finding all zichuan in a string that is the same as that substring. In programming languages, pattern matching is used to determine whether a pattern exists for a type or value that can be matched.

In Rust, the match branch has patterns on the left and code on the right. A pattern match can also be an expression. Like an if expression, all branches must return the same type. But the pattern on the left can be different. In the code, the patterns used are single value, range, multiple values, and wildcards. The @ operator can bind the value of the pattern to a variable for use by code on the right side of the branch. This type of matching is called Binding Mode. The ** match expression must exhaust every possibility, so in general, the wildcard _ is used to handle the rest. In addition to match expressions, pattern matching is used in let bindings, function parameters, and for loops.

If let and while let expressions

Rust provides if let and while let expressions, respectively, to replace match expressions in certain situations.

fn main () { let boolean = true; let mut binary = 0; if let true = boolean { binary = 1; } assert_eq! (binary, 1); }Copy the code

The code listing uses an if let expression, similar to a match expression, with patterns on the left and values to match on the right. If Boolean is true, change binary to 1. In some cases where loops are used, you can also use a while let to simplify code

fn main () { let mut v = vec! [1, 2, 3, 4, 5]; loop { match v.pop() { Some(x) => println! ("{}", x), None => break, } } }Copy the code

In the code above, you create a dynamic array V, and you want to print its elements out at once using the POP method. The loop is used here because the pop method calling V returns the Option type. So match matches both cases, Some(x) and None. The Option type is introduced in Rust to prevent null Pointers. Some(x) matches elements of the array summary, while None matches when the array is empty, breaking out of the loop when it is empty (break).

The while let simplifies the above code

fn main () { let mut v = vec! [1, 2, 3, 4, 5]; while let Some(x) = v.pop() { println! ("{}", x); }}Copy the code

In this code, we use the while let expression, similar to the if let. Some(x) on the left of it matches the Option type result returned by the pop method call on the right, and automatically creates an X binding for println! The macro statement is used to automatically jump out of the loop if the value in the array is empty.

# Rust learning