Conditional statement is based on {if, else} keywords. You can create two program branches. When a condition is true then first branch is executed. When the condition is false the other branch is executed. The else branch is optional but the first is mandatory.
Conditional Execution
fn main() {
let a = 10;
let b = 10;
if a == b {
println!("a and b are equal"); //expected
}
else
{
println!("a and b are not equal"); //unexpected
}
}
In many languages the decision is only a statement. In Rust the if is actually an expression that can have a result. The result is given by the value of the last expression in the block. This is specific to Rust and looks a little bit strange for programmer. Sometimes may be useful to think like this especially when there is no ternary operator like "?" used in other languages.
/* demo for conditional expression */
fn main() {
let condition: bool = false; //boolean
let number = if condition { 5 } else { 6 };
println!("The value of number is: {}", number);
}
Note:
5
and 6
are enclosed in a small blocks { 5 }, {6}bool,
6
except if you modify it.In Python we use elsif keyword and in Julia we use elseif keyword to create a multi-deck decision. Here in Rust we do not have a such keywords. Instead you can use else if that are two keywords. This is possible in Rust due to lack of any symbol required after the "else". In Python after else you must use ":" but in Rust you can use a block { ... } or another if statement to for a multi-path decision block.
Decision Ladder
fn main() {
use std::io;
/* read a number */
println!("enter a number:");
let mut input = String::new();
io::stdin().read_line(&mut input).unwrap();
let number: i32 = input.trim().parse().unwrap();
/* check number */
if number % 2 == 0 {
println!("this number is divisible by 2");
} else if number % 3 == 0 {
println!("this number is divisible by 3");
} else if number % 5 == 0 {
println!("this number is divisible by 5");
} else if number % 7 == 0 {
println!("this number is divisible by 7");
} else {
println!("this number is not divisible by 2,3,5 or 7");
}
println!("done");
}
Homework:Open this example and run it: ladder
There is one more control statement that is very important in Rust. This will replace "switch" or "case" that is available in Julia and Level. The idea of this statement is simple. We create a structure to check several conditions. We execute one statement for witch the condition is true. The beauty of Rust is that this condition is verified such way that all cases are covered. If we do not cover all cases a compiler error will be generated. "match" is one of the most powerful things in Rust.
/* define enumeration */
enum Coin {
Nickel,
Dime,
Quarter,
}
/* use "match" statement */
fn penny(coin: Coin) -> u32 {
match coin {
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter => 25,
}
}
/* test penny() function */
fn main() {
use Coin::{Quarter, Dime, Nickel};
println!("A quarter has {} penny",penny(Quarter));
println!("A dime has {} penny",penny(Dime));
println!("A Nickel has {} penny",penny(Nickel));
}
Homework: This example is on repl.it. Open and run it: penny
This is the most simple repetition statement. We use only keyword "loop" and { ... } to create a repetitive block. This will be repeated forever and the program will get stack in the loop. You can stop using CTRL+C. This is actually a logical error. Good programmers must avoid infinite loops at all cost.
Loop Diagram
fn main() {
loop {
println!("press ctrl+c to stop me!");
}
}
Note: This example is not available to be run, it is rude to block the session.
You can intrerupt a loop by using breack and continue statements. These two statements are optional. If a repetitive statement has too many intreruptions is hard to read, so avoid using these statements as much as possible.
To avoid an infinite loop you must create a break using a conditional stop.In the next example we create a control variable "i" that is declared outside of the loop and start with 1. Then you can increment this variable with +1 every iteration. You can use the relation operator "i > 3". This loop will execute 3 times then will stop and program will terminate.
Loop Break
fn main() {
let mut i = 1;
loop {
println!("Variable i is now {}!",i);
if i > 3 {
break;
} else {
i += 1;
} //end if
} // end loop
} // end main
You can use continue
keyword to start over. This will create a kind of shortcut that will skip all other statements and restart the loop. You can continue a loop from inside a nested block.
Loop Continue
fn main() {
let mut i = 1;
loop {
if i < 3 {
i += 1;
println!("Variable i is now {}!",i);
continue;
} break;
} // end loop
} // end main
This is a repetitive block of code that is executed as long as one condition is true. When the condition become false the program continue with next statement after the loop block end. Now the problem is to create a condition expression that will become false. If the condition never become false we again can have an infinite loop.
While Loop
fn main() {
let mut number = 3;
while number != 0 {
println!("{}!", number);
number = number - 1;
} // end while
println!("LIFTOFF!!!");
} // end main
This kind of loop is created using keyword "for" and it has two usages: One is to iterate a specific number of times over a range of numbers. Second is to iterate over a collection of items: array, vector, string or map/dictionary. The range in Rust is created using a range expression with .. operator. (1..10) will create one number and will assign it to "i" to create the control variable.
For Loop
with continue & break
Syntax
// display numbers 0 to 9;
for i in range {
//first block
if condition {
continue;
}
//second block
if condition {
break;
}
//third block
}//end for
Example 1: Range Loop
Next program demonstrate range 0..10, we observe last number is 9 and not 10. The range do not include the outer limit. This is how ranges work in Rust. This loop do not have any alterations (break/continue) are not used.
// display numbers 0 to 9;
fn main() {
// the lust number i will not be generated that is the Range definition
for i in 0..10 {
println!("{}!", i);
}//end for
println!("done!");
} //end main
Example 2: Nested Loops
Next program demonstrate nested loops. We generate prime numbers. The inner loop has an alteration. We break the loop if the number is not a prime number.
// generate prime numbers < 30
fn main() {
for i in 1..30 {
for j in 2..i {
if (i % j) == 0 {
break;
};
if j == (i-1) {
print!("{},", i);
};
};
}//end for
println!("done!");
} //end main
Homework: This example is available on repl.it for testing. open on repl.it and run it. Then modify the program to generate prime numbers < 1000.
This is the most useful loop that is actually the iterative loop. It will visit each item from a collection until the last element is visited. The peculiar thing specific to Rust is that we have to specify method "iter()" to get an iterator that is actually a function that can be used to fetch the next element.
fn main() {
let a = [10, 20, 30, 40, 50];
// next we iterate over all members of array "a"
for element in a.iter() {
println!("the value is: {}", element);
} // end for
} // end main
Read next: Functions