Control Structures
Control structures allow programers to insturct computers how to behave when faced with certian conditions.
Common control structures include:
- if statements
- else statements
- for loops
- while loops
We can relate the logic of these control sturtures to situations that we encounter in our lives.
For example: I could be at the grocery store looking at a bag of chips and think to myself: "if I add this bag of chips to my cart, I will likely eat its entire contents before I get home and feel like trash for the rest of the night."
A program that executes that logic could look like this:
fn main(){ // declare main function let chips=true; // use let statement to exhibit my lack of self control if chips { // declare if statement with boolean condition println!("I ate the whole bag of chips and feel like trash") // print result if true } // close if expression } // close main function expression
Else statements tell the computer to do an action if the first condition is not met.
Using the first example, we can create an if-else control structure that runs code when the first condition is not true:
fn main(){ // declare main function let chips=false; // use let statement to exhibit my outstanding self control if chips { // declare if statement with boolean condition println!("I ate the whole bag of chips and feel like trash") // print result if true } else { // close if expression println!("Good work, idiot. You practiced self control!") // print supportive message } // close else expression } // close main function expression
We can combine let and if statements. These statements might be useful when there are variables in our code that are condition-dependent. For example, after I finish a swim workout, my body looks gorgeous. However, on days when I don't swim, my body looks like a bony meat bag. A program that executes that logic could look like this:
fn main(){ // declare main function let swim=true; // declare boolen swim variable let gorgeous = if swim {["went for a swim", "gorgeous"]} else {["didn't for a swim", "like a bony meat bag"]}; // boolean let-if statement println!("Cassidy {}, and his body looks {}", gorgeous[0], gorgeous[1]); // print result of let-if statement } // close main expression
The rust compiler expects let-if epressions to produce the same data types. For example, the program below evaluates boolean conditions and outputs what people might call Toronto based on a pre-defined age.
fn main() { let age=28; // create variable using let statement and boolean true let toronto = if age <= 26 {"6"} else if age > 26 && age < 86 {"Tdot"} else {"The Big Smoke"}; // declare let-if statement with expressions println!("My age is {age} and I call Toronto {toronto}", age=age.to_string(), toronto=toronto) }
Below, we change the expression data type for the people who refer to Toronto as "The Six." Becasue we changed the output data type of this expression, the compiler returns an error.
fn main() { let age=28; // create integer variable using let statement let toronto = if age <= 26 {6} else if age > 26 && age < 86 {"Tdot"} else {"The Big Smoke"}; // declare let-if statement with expressions println!("My age is {age} and I call Toronto {toronto}", age=age.to_string(), toronto=toronto) }
Loops allow us to do stuff fast. Rust has three loop types: for, loop, and while.
For loops run for perscribed iterations. In the example below, I created an array filled with events from a rec-league hockey game in which a player on the other team punched me, cowered behind the ref after I confronted him, and his teammate tried to intimidate the smallest player on our team. The for loop runs through the elements in the array, and the println! macro outputs each event with an intenisty integer. The intensity integers increase exponentially.
fn main() { let mut intensity = 0; // declare mutable variable using a let statement let problems: [&str; 5] = ["A guy punched me", "The guy who punched me skated away after I confronted him", "The guy who punched me whined to the ref after he skated away", "The guy who punched me was too scared to look at me for the rest of the game", "The 220 lb teammate of the guy who punched me tried to intimidate the smallest player on our team"]; // declare array of problems, and specify data type and length for problem in problems { // for loop that iterates through elements in array if intensity < 2 { // boolean check until multiplication can represent exponential growth intensity += 1; // increment intensity } else { // if intensity is greater than 2, the following expression can use multiplication to represent exponential growth intensity = intensity * intensity // multiply intensity by itself and redefine variable } println!("{problem}. The intensity is now {intensity}", problem=problem, intensity=intensity.to_string()) // print current intensity } // close for loop }
Loop loops run until they're told to stop. For example, a program could contain a boolean-if statement that checks for the number of iterations the program has completed. If the number of iterations triggers a true response from the if-expression, the programmer can use a break statement to end the loop.
fn main() { // create main function let mut loops: u8 = 0; // assign mutable, unsiged, eight-bit integer to variable using let statement loop { // open loop expression if loops < 10 { // boolean check if current loop is less than ten loops+=1; // increment loop number println!("Loop number {}", loops); // print number of loops } else { // boolean else break // break out of loop if current iteration is >= 10 }; // close else expression }; // close loop expression } // close main function
While loops run while a boolean condition is true. For example a while loop may run until an element in an array is found.
fn main() { // open main expression let characteristics: [&str; 4] = ["Saquon Barkley", "Cassidy MacDonald", "got dem quads", "got that dog in him"]; // declare array of static strings let mut i: usize = 0; // declare mutable index counter using usize type while characteristics[i] != "got dem quads" { // while loop that iterates through elements in array println!("{} {}", characteristics[i], characteristics[2]); // print the facts println!("{} {}", characteristics[i], characteristics[3]); // print the facts i+=1; // increment counter }; // close while loop } // close main expression
Break and continue statements allow us to control loops. Break statements end loops and continue makes the program move on to the next iteration. For example, if you were playing monopoly with a resonable person and they caught you cheating, you may let them pass go before continuing the game. An un reasonable person, in contrast, may throw a temper tantrum and break the game. A program that demonstrates that scenario follows:
fn main() { // open main expression let cheating: [bool; 7] = [true, false, true, false, true, false, true]; // declare array of events let reasonable: [bool; 7] = [true, false, false, false, true, false, true]; // declare array of events let mut i: usize = 0; // declare index pointer for cheat in cheating { // open for loop that iterates through boolean array if reasonable[i] & cheat { // boolean if statement that checks if the players are reasonable and cheating println!("Pass go"); // print outcome i += 1; // increment counter continue; // continue } else if !reasonable[i] & cheat { // boolean if that checks if the players are not reasonable and cheating println!("Break that shit, King Kong"); // print outcome break; // Asshole broke the game }; // close expression i += 1; // increment counter if both conditions are not true } // close loop expression } // close main expression
Break and control statements can also be associated with specific loops. For example, you could use this if you had two arrays of names and to check if there were name duplicates.
fn main() { // open main expression let names_1: [&str; 4] = ["Fred", "Cocco", "Sally-Anne", "Ron"]; // declare array of names let names_2: [&str; 4] = ["Judy", "George", "Cocco", "Jen"]; // declare array of names 'list_1: for name_1 in names_1 { // open for loop that iterates through names_1 array for name_2 in names_2 { // open second for loop that iterates through second array if name_2 == name_1 { // boolean check to see if there are duplicate names println!("{name_1} is in array one and {name_2} is in array two", name_1=name_1, name_2=name_2); // print result if match break 'list_1 // break out of outer loop } // close if expression } // close inner loop expression } // close outer loop expression } // close main expression