📄 Introduction
Learn how Rust makes decisions, repeats logic smartly, and keeps your code clean using control flow and reusable functions.
In Rust Foundations, we explored Rust’s core data tools — variables, mutability, shadowing, and data types.
But real programs do more than store data — they make decisions, repeat logic, and organize behavior. That’s where control flow and functions come in.
In this post, you’ll learn how to:
- Make choices with if and match
- Repeat tasks using loop, while, and for
- Build reusable blocks with the fn keyword
Each section includes:
- Real-world examples
- “Try It Yourself” mini challenges
- Key Rust features explained
Let’s begin with one of Rust’s simplest yet most powerful tools: Conditional branching with if.
if Expressions – Make Decisions with Conditions
📁 Create a new project to explore if
Let’s start with a fresh Rust project to practice conditional branching using if
expressions:
cargo new if_elseif_eg
cd if_elseif_eg
This creates a new folder with a basic Rust project and a starter main.rs file under the src directory. We’ll use this file to explore how Rust handles decision-making using if
, step by step.
Screenshot : A new Rust project named if_elseif_eg has been successfully created.
⁉️ Why if Matters in Rust
In any real-world program, we need logic to decide what happens next—whether it’s a yes or no, a range check, or reacting to user input. In Rust, the if
expression helps your program take decisions based on conditions.
Rust enforces that every condition must return a bool
— no implicit 0 or 1 like in C/C++.
Let’s warm up with a practical example.
🔖 Keywords & Concepts Used in This Program
Here’s a quick breakdown of the key Rust elements used in this program:
Keyword | Concept |
---|---|
use std::io |
Imports Rust’s input/output library |
let mut temp = String::new() |
Declares a mutable string variable |
read_line() |
Reads input from the terminal |
expect() |
Handles possible input errors (panics if failed) |
trim() |
Removes trailing newline from input string |
if , else if , else |
Controls branching logic based on condition |
println!() |
Prints formatted output to the console |
Example: if Expression – Temperature Categorizer
Let’s now write a simple program that takes user input and tells if the day is Hot, Warm, Cool, or Cold.
Screenshot : main.rs
with code to categorize temperature
Screenshot : VS code terminal output of temperature categorizer
💭 Try it yourself
Let’s reinforce your learning with two small challenges using conditional branching if
💡 Challenge 1: 🔢 Odd or Even Checker
Ask the user for a number and print whether it's Odd or Even.
⏳ Try writing this on your own before checking the solution!
✅ Show Solution
use std::io;
fn main() {
println!("Enter a number :");
let mut n = String::new();
io::stdin().read_line(&mut n).expect("Failed to read input");
let n: i32 = n.trim().parse().expect("Please enter a valid number");
if n % 2 == 0{
println!("The number {n} is Even");
} else {
println!("The number {n} is Odd");
}
}
💡 Challenge 2: 📦 Shipping Fee Calculator
Ask the user for: Order amount in ₹ , Delivery distance in km .Then apply the nested if
logic shown above to print the shipping fee.
⏳ Try writing this on your own before looking at the solution!
✅ Show Solution
use std::io;
fn main() {
println!("Enter the order amount :");
let mut amt = String::new();
io::stdin().read_line(&mut amt).expect("Failed to read line");
let amt: i32 = amt.trim().parse().expect("Please enter a valid number");
println!("Enter the distance in Km :");
let mut dist = String::new();
io::stdin().read_line(&mut dist).expect("Failed to read line");
let dist: i32 = dist.trim().parse().expect("Please enter a valid number");
if amt > 500 {
if dist <= 10 {
println!("Free shipping 🚚");
} else {
println!("Shipping Fee: ₹20");
}
} else if amt >= 200 {
if dist <= 10 {
println!("Shipping Fee: ₹50");
} else {
println!("Shipping Fee: ₹70");
}
} else {
if dist <= 10 {
println!("Shipping Fee: ₹100");
} else {
println!("Shipping Fee: ₹120");
}
}
}
In the next section, let’s look at how Rust keeps repeating tasks smartly — using
loop
,while
, andfor
.
Loop Forever? Not Without a break
📁 Create a new project to explore loop
⚠️ We repeat the project creation in each section to reinforce best practice — always start with a clean project when testing individual concepts in Rust.
Let’s create a new Rust project to explore how to repeat tasks using the loop
expression — Rust’s way of writing infinite loops.
cargo new loop_eg
cd loop_eg
This creates a new folder with a basic Rust project and a starter main.rs file under the src directory. We’ll use this file to explore how Rust handles infinite looping using loop, step by step.
Screenshot : A new Rust project named loop_eg has been successfully created.
⁉️ Why loop Matters
In Rust, loop is an infinite loop—it runs forever unless you break it manually.
This is useful when:
- You want to keep retrying (e.g., password prompts, login)
- You’re building games or input handlers
- When the number of repetitions isn’t known beforehand
Let’s build a fun logic game using loop and break.
🔖 Keywords & Concepts Used in This Program
Here’s a quick breakdown of the key Rust elements used in this program:
Keyword | Concept |
---|---|
loop |
Starts an infinite loop |
break |
Stops the loop when condition is met |
rand::Rng , gen_range() |
Generates random numbers |
let mut |
Declares a mutable score and input |
read_line() + parse() |
Reads and converts user input |
match |
Handles input validation and error fallback |
if / else |
Controls score increment or feedback logic |
println!() |
Prints messages and feedback to the user |
Example: Math Quiz – Break After 3 Correct Answers
To see loop and break
in action, let’s build a small Math Quiz game. The program will:
- Keep asking random math questions
- Break the loop when the user answers 3 correctly
Screenshot : main.rs
with code for Math Quiz
Screenshot : Terminal output of Math Quiz in VS Code
Add the rand crate to Cargo.toml
To generate random numbers, we need the
rand
crate. Open your Cargo.toml and add:
[dependencies]
rand = "0.8.5" # Use the latest version
You can find the latest version from crates.io/crates/rand
Screenshot : cargo.toml
with rand dependency
💭 Try It Yourself
Let’s reinforce your learning with two small challenges using infinite loop
and break
.
💡 Challenge 1: 🎲 Dice Roller Until 6
Simulate rolling a dice using random numbers. Keep looping until you get a 🎲 six. Track the number of attempts. Can you guess how lucky you are?
⏳ Try writing this on your own before checking the solution!
✅ Show Solution
use rand::Rng;
fn main() {
let mut a = 0; //a: attempts
loop {
let r = rand::thread_rng().gen_range(1..=6); //r: roll
a += 1;
println!("🎲 You rolled: {}", r);
if r == 6 {
println!("You got a 6 in {} attempts!", a);
break;
}
}
}
💡 Challenge 2: 💧Simulate a Water Cycle
Print the 4 stages of the water cycle – evaporation, condensation, precipitation, collection – in order, and loop the full cycle 3 times. Use an array and a loop!
⏳ Try writing this on your own before looking at the solution!
✅ Show Solution
fn main() {
let s = ["Evaporation 🌫", "Condensation ☁️", "Precipitation 🌧", "Collection 💧"]; //s: stages
let mut c = 0; //c:count
loop {
println!("Cycle {}:", c + 1);
for stage in &s {
println!(" → {}", stage);
}
c += 1;
// You can change 'c' to simulate more rounds.try 5, 10… but beware: too many cycles = water overload! 🌊
if c == 3 {
println!("🌍 3 cycles completed. Simulation ends.");
break;
}
println!("--- Repeating the water cycle ---\n");
}
}
What if you don’t want to loop forever — but only as long as a condition holds true?
while Loops – Repeat Based on a Condition
📁 Create a new project to explore while
Let’s start with a fresh Rust project to explore how to repeat a task while a condition holds true using while
expressions:
cargo new while_eg
cd while_eg
This creates a new folder with a basic Rust project and a starter main.rs file under the src directory. We’ll use this file to explore how Rust handles repeat a task based on a condition using while, step by step.
Screenshot : A new Rust project named while_eg has been successfully created.
⁉️ Why while Matters
Unlike loop, which repeats forever until you break, a while loop keeps running only as long as a condition is true.
It’s great when:
- You don’t know how many times to repeat
- You stop based on some dynamic or external condition
- You want cleaner and safer loops that won’t go infinite accidentally
Let’s build something meaningful with it.
🔖 Keywords & Concepts Used in This Program
Here’s a quick breakdown of the key Rust elements used in this program:
Keyword | Concept |
---|---|
use std::io |
Imports Rust’s input/output library |
let mut n = String::new() |
Declares a mutable string variable |
read_line() |
Reads input from the terminal |
expect() |
Handles possible input errors (panics if failed) |
trim() |
Removes trailing newline from input string |
let mut a = 0/let mut b = 1 |
Declares mutable variables for sequence tracking |
while condition |
Repeats as long as a is less than or equal to n |
print!() |
Prints the sequence on the same line |
a = b; b = a + b |
Updates variables to get the next number in the sequence |
Example: Fibonacci Series Generator
Generate the Fibonacci sequence until user limit using a while
loop.
Screenshot : main.rs
with code for Fibonacci generator
Screenshot : Terminal output of Fibonacci generator
💭 Try it Yourself
Let’s reinforce your learning with two small challenges using repetitive task while
.
💡 Challenge 1: 🛒 Cart Total Until Budget
Ask the user to keep entering item prices. Stop when the total exceeds ₹1000. Use a while
loop to accumulate and break once the budget is crossed. Track the number of items too!
⏳ Try writing this on your own before checking the solution!
✅ Show Solution
use std::io;
fn main() {
let mut t = 0.0; //t: total
let mut c = 0; //c: count
println!("🛒 Add item prices to your cart (budget: ₹1000)");
while t <= 1000.0 {
let mut x = String::new();
println!("Enter price of item {}:", c + 1);
io::stdin().read_line(&mut x).expect("Failed to read input");
let y: f32 = match x.trim().parse() { //y: price
Ok(p) => p,
Err(_) => {
println!("⚠️ Please enter a valid number.");
continue;
}
};
t += y;
c += 1;
println!("✅ Item added. Current total: ₹{:.2}", t);
}
println!("\n💸 Budget exceeded! You added {} items. Final total: ₹{:.2}", c, t);
}
💡 Challenge 2: 🔐 Secret Number Guessing Game
Use a loop
and rand::gen_range()
to generate a secret number between 1 and 20. Let the user keep guessing until they get it right. Give hints like "Too high" or "Too low" after each guess. Track the number of attempts. Can you guess it in under 5 tries?
⏳ Try writing this on your own before looking at the solution!
✅ Show Solution
use rand::Rng;
use std::io;
fn main() {
let s = rand::thread_rng().gen_range(1..=20); //s: secret_number
let mut a = 0; //a: attempts
println!("🎯 Guess the secret number (1–20)");
loop {
let mut g = String::new(); //g: guess
println!("Enter your guess:");
io::stdin().read_line(&mut g).expect("Failed to read");
let g: u32 = match g.trim().parse() {
Ok(num) => num,
Err(_) => {
println!("⚠️ Please enter a valid number.");
continue;
}
};
a += 1;
if g < s {
println!("🔻 Too low! Try again.");
} else if g > s {
println!("🔺 Too high! Try again.");
} else {
println!("🎉 Correct! You guessed it in {} attempts.", a);
break;
}
}
}
for Loops – Iterate Over Ranges and Collections
📁 Create a new project to explore for
Let’s start with a fresh Rust project to practice iterative tasks using for
over ranges and collections
cargo new for_eg
cd for_eg
This creates a new folder with a basic Rust project and a starter main.rs file under the src directory. We’ll use this file to explore how Rust iterates over ranges and collections using the for loop, step by step.
Screenshot : A new Rust project named for_eg has been successfully created.
⁉️ Why for Matters
Rust’s for loop is the cleanest way to repeat a task a specific number of times or iterate over a collection.
Use it when:
- You know exactly how many times to loop
- You want to loop over a list, range, or array
- You prefer concise and readable syntax
Let’s use it to display some cool number patterns.
🔖 Keywords & Concepts Used in This Program
Here’s a quick breakdown of the key Rust elements used in this program:
Keyword | Purpose |
---|---|
use std::io |
Imports Rust’s input/output library |
let mut n = String::new() |
Declares a mutable string variable |
read_line() |
Reads input from the terminal |
expect() |
Handles possible input errors (panics if failed) |
trim() |
Removes trailing newline from input string |
for i in 1..=count |
Loops from 1 to N (inclusive) |
let mut |
Mutable string for user input |
parse() |
Converts input string to number |
println!() formatting |
Displays numbers with spacing and formatting |
Example: Display Cube and Square of N Numbers
Calculate cube and square of numbers specified by user using for
loop.
Screenshot : main.rs
with code to calculate cube and square of numbers
Screenshot : Terminal output of cube and square in VS code
💭 Try it Yourself
Let’s reinforce your learning with two small challenges using for loop to perform repetitive tasks over ranges and values.
💡 Challenge 1: ✖️ Generate Multiples of a Number
Ask the user to enter a number (like 7)
Use a for
loop to display: 7, 14, 21, ..., up to 12 times.
Can you format the output horizontally or show it in a table?
⏳ Try writing this on your own before checking the solution!
✅ Show Solution
use std::io;
fn main() {
let mut n = String::new();
let c = 12;
println!("Enter a number to generate its multiples:");
io::stdin().read_line(&mut n).expect("Failed to read input");
let n: u32 = n.trim().parse().expect("Please enter a valid number");
println!("\n📈 First {} multiples of {}:", c, n);
for i in 1..=c {
println!("{} × {} = {}", n, i, n * i);
}
}
💡 Challenge 2: 🎯 FizzBuzz – Classic Loop Challenge
Print numbers from 1 to 20. If divisible by 3, print Fizz
; if divisible by 5, print Buzz
; and for both, print FizzBuzz
.
Use a for
loop with if-else
conditions.
⏳ Try writing this on your own before looking at the solution!
✅ Show Solution
fn main() {
println!("🎲 FizzBuzz from 1 to 20:");
for i in 1..=20 {
if i % 3 == 0 && i % 5 == 0 {
println!("{} → FizzBuzz", i);
} else if i % 3 == 0 {
println!("{} → Fizz", i);
} else if i % 5 == 0 {
println!("{} → Buzz", i);
} else {
println!("{}", i);
}
}
}
match – Pattern Matching the Rust Way
📁 Create a new project to explore match
Let’s start with a fresh Rust project to practice pattern matching using match
cargo new match_eg
cd match_eg
This creates a new folder with a basic Rust project and a starter main.rs file under the src directory. We’ll use this file to explore how Rust matches patterns using the match expression, step by step.
Screenshot : A new Rust project named match_eg has been successfully created.
⁉️ Why match Matters
Rust’s match
is a superpower. It’s like a switch case in other languages — but safer, exhaustive, and more expressive.
Use it when:
- You want to compare a value against different patterns
- You want clean alternatives to messy if-else chains
- You’re handling user choices, enums, error types, or menu-driven programs
Let’s explore pattern matching with a fun example!
🔖 Keywords & Concepts Used in This Program
Here’s a quick breakdown of the key Rust elements used in this program:
Keyword | Concept |
---|---|
use std::io |
Imports Rust’s input/output library |
let mut p = String::new() |
Declares a mutable string variable |
read_line() |
Reads input from the terminal |
expect() |
Handles possible input errors (panics if failed) |
trim() |
Removes trailing newline from input string |
rand::Rng , gen_range(0..3) |
Randomly selects computer’s choice |
match (p, c) |
Matches tuple of player and computer choices |
as_str() and trim() |
Normalizes user input for comparison |
Example: Rock, Paper and Scissors - You vs Computer!
Let’s see how match can be used to compare multiple possibilities at once. We’ll build a fun game of Rock, Paper, Scissors — where you play against the computer!
Screenshot : main.rs
with code to play Rock, Paper and Scissors
Screenshot : Terminal output of match expression game
Add the rand crate to Cargo.toml
To generate random numbers, we need the
rand
crate. Open your Cargo.toml and add:
[dependencies]
rand = "0.8.5" # Use the latest version
You can find the latest version from crates.io/crates/rand
Screenshot : cargo.toml
with rand dependency
💭 Try it Yourself
Let’s reinforce your learning with two small challenges using match
.
💡 Challenge 1: 🗓️ Month Number to Name
Ask the user to enter a month number (1 to 12). Use a match
expression to print the full month name.
For anything outside 1–12, display "Invalid month".
⏳ Try writing this on your own before checking the solution!
✅ Show Solution
use std::io;
fn main() {
println!("Enter the month number (1–12):");
let mut m = String::new();
io::stdin().read_line(&mut m).expect("Failed to read input");
let m: u32 = match m.trim().parse() {
Ok(num) => num,
Err(_) => {
println!("❌ Please enter a valid number.");
return;
}
};
let month = match m {
1 => "January",
2 => "February",
3 => "March",
4 => "April",
5 => "May",
6 => "June",
7 => "July",
8 => "August",
9 => "September",
10 => "October",
11 => "November",
12 => "December",
_ => "Invalid month!",
};
println!("📅 Month: {}", month);
}
💡 Challenge 2: ✔️ Language Selector
Ask the user for their name and preferred language.
Use match
to print a personalized greeting like வணக்கம் Ravi or Hola Aisha.
Hint: Combine trim()
, to_lowercase()
, and println!
to make the message dynamic.
⏳ Try writing this on your own before looking at the solution!
✅ Show Solution
use std::io;
fn main() {
// Step 1: Ask for user's name
println!("🧑💻 Enter your name:");
let mut name = String::new();
io::stdin().read_line(&mut name).expect("Failed to read name");
let name = name.trim(); // Clean up newline
// Step 2: Ask for preferred language
println!("🌐 Choose a language (tamil, malayalam, hindi, french, spanish):");
let mut lang_input = String::new();
io::stdin().read_line(&mut lang_input).expect("Failed to read input");
let lang = lang_input.trim().to_lowercase();
// Step 3: Match input and print greeting
match lang.as_str() {
"tamil" => println!("👋 வணக்கம் {}!", name),
"malayalam" => println!("👋 നമസ്കാരം {}!", name),
"hindi" => println!("👋 नमस्ते {}!", name),
"french" => println!("👋 Bonjour {}!", name),
"spanish" => println!("👋 Hola {}!", name),
_ => println!("⚠️ Sorry, I don't know that language yet, {}!", name),
}
}
Functions – Reusable Building Blocks in Rust
📁 Create a New Project to Explore fn Functions
Let’s start with a fresh Rust project to practice writing and calling functions using the fn
keyword.
cargo new func_eg
cd func_eg
This creates a new folder with a basic Rust project and a starter main.rs file under the src directory. We’ll use this file to explore how Rust lets you define modular, reusable blocks of logic using functions, step by step — with and without return values.
Screenshot : A new Rust project named func_eg has been successfully created.
⁉️ Why fn Matters
Functions let you:
- Group code into named, reusable blocks
- Keep logic clean and modular
- Pass data (parameters) and get results (return values)
Rust uses fn
to declare functions. Let’s build one with inputs, returns, and logic!
🔖 Keywords & Concepts Used in This Program
Here’s a quick breakdown of the key Rust elements used in this program:
Keyword | Concept |
---|---|
use std::io |
Imports Rust’s input/output library |
let mut shape = String::new() |
Declares a mutable string variable |
read_line() |
Reads input from the terminal |
expect() |
Handles possible input errors (panics if failed) |
trim() |
Removes trailing newline from input string |
fn function_name() |
Declares a named function |
-> f32 |
Return type of the function |
match with function calls |
Calls specific area function based on shape |
String::new() |
Mutable input variable |
parse::<f32>() |
Convert input string to floating point |
Example: Area Calculator – Square, Rectangle, Triangle
Let’s see how fn
can be used to reuse logic cleanly. We’ll build an area calculator that asks for a shape and uses a function for each shape to compute the area
Screenshot : main.rs
with code to calculate area of square, rectangle and triangle
Screenshot : Terminal output of area of different shapes
💭 Try it Yourself
Let’s reinforce your learning with two small challenges using reusable logic fn
💡 Challenge 1: 🔢 Factorial with Recursion
Ask the user for a number, and write a recursive function
that returns its factorial.
Base case: if 0 → return 1.
Recursive case: n × factorial(n - 1)
⏳ Try writing this on your own before checking the solution!
✅ Show Solution
use std::io;
fn main() {
println!("🔢 Enter a number to find its factorial:");
let mut input = String::new();
io::stdin().read_line(&mut input).expect("Failed to read input");
let num: u32 = input.trim().parse().expect("Please enter a valid number");
let result = factorial(num);
println!("Factorial of {} is {}", num, result);
}
// Recursive function to calculate factorial
fn factorial(n: u32) -> u32 {
if n == 0 {
1
} else {
n * factorial(n - 1)
}
}
💡 Challenge 2: 🔡 Reverse a String
Ask the user for a word or sentence. Write a function that takes a &str
and returns it reversed.
Use: s.chars().rev().collect()
⏳ Try writing this on your own before looking at the solution!
✅ Show Solution
use std::io;
fn main() {
println!("🔁 Enter a word or sentence to reverse:");
let mut i = String::new(); //i: input
io::stdin().read_line(&mut i).expect("Failed to read input");
let og = i.trim(); //og: original string
let rev = reverse_string(og); //rev: reversed string
println!("🔄 Reversed: {}", rev);
}
// Function to reverse a string
fn reverse_string(s: &str) -> String {
s.chars().rev().collect()
}
🎯 Conclusion – You’ve Built the Core!
You’ve just completed one of the most empowering stages of your Rust journey!
In this post, you didn’t just learn control flow and functions — you actually used them to build mini tools, games, and interactive apps. From branching logic with if
and match
, to loops that think (loop
, while
, for
), and clean, reusable fn
functions — you now hold the real levers of Rust’s logic engine.
Each section you’ve explored lays another brick in your foundational wall:
- Logic with if-else, power with loop / while / for
- Elegance through match
- Reusability via functions
- Real interaction with user input
Try revisiting any section or challenge if you want to deepen your understanding — and feel free to share your favorite mini project or a new twist of your own!
Next on Techn0tz -
Rust Foundations – Part 3: Bringing It All Together,
we’ll bring all your new Rust skills together to build a complete, meaningful project — from input to output, decision to display.
Stay tuned — your first full Rust program awaits!