๐ฆ Rust Series 2: Control Flow, Functions, and Ownership


Rust is a powerful systems programming language that enforces memory safety without a garbage collector. In this post, we will explore control flow (conditionals & loops), functions, and ownership concepts (move vs. borrowing).
๐ Conditionals in Rust
Rust provides if
, else if
, and else
statements to control the program flow.
fn main() {
println!("\n===== CONDITIONALS IN RUST =====");
let is_user_logged_in = true;
let is_user_paid = true;
let is_admin = false;
if is_user_logged_in {
println!("User is logged in");
}
if is_admin {
println!("Admin panel is accessible");
} else {
println!("Regular user dashboard");
}
if is_admin {
println!("Welcome, Admin!");
} else if is_user_paid && is_user_logged_in {
println!("Welcome, Premium User!");
} else if is_user_logged_in {
println!("Welcome, Free User!");
} else {
println!("Please log in to continue");
}
let access_level = if is_admin {
"admin"
} else if is_user_paid {
"premium"
} else {
"basic"
};
println!("Access level: {}", access_level);
}
๐ ๏ธ Loops in Rust
Rust supports different types of loops:
1. Infinite Loop (loop
)
let mut counter = 0;
loop {
println!("Counter is: {}", counter);
counter += 1;
if counter == 5 {
break;
}
}
2. Labeled Loops ('label: loop
)
let result = 'counter_loop: loop {
counter += 1;
if counter == 10 {
break 'counter_loop counter * 2;
}
};
println!("Loop result: {}", result);
3. while
Loop
let mut number = 1;
while number < 5 {
println!("Number is: {}", number);
number *= 2;
}
4. for
Loop (Iterating over Ranges)
for i in 1..=5 {
println!("i is: {}", i);
}
๐ง Functions in Rust
Functions help organize code into reusable logic blocks. Rust enforces explicit return types.
fn sum_of_two_numbers(num1: i32, num2: i32) -> i32 {
num1 + num2
}
fn sum_of_numbers(n: i64) -> i64 {
n * (n + 1) / 2
}
fn main() {
println!("\n===== FUNCTIONS =====");
let sum_result = sum_of_two_numbers(15, 27);
println!("Sum of 15 and 27 is: {}", sum_result);
let n = 1000;
let sum_n = sum_of_numbers(n);
println!("Sum of numbers from 1 to {} is: {}", n, sum_n);
}
๐ค Ownership, Borrowing, and String Handling in Rust
Rust prevents data races and use-after-free errors using ownership rules.
๐ Example: Extracting Words from a Sentence
fn main() {
let sentence = String::from("Hello rusty, welcome to world of rust");
let first_word_from = get_first_word(&sentence);
println!("First word from sentence is : {}", first_word_from);
let first_letter_from = get_first_letter(&sentence);
println!("First letter from sentence is : {}", first_letter_from);
let return_asked_index = get_index_of(&sentence, 2);
println!("Index of rust in sentence is : {}", return_asked_index);
}
fn get_first_word(sentence: &str) -> String {
let mut ans = String::new();
for char in sentence.chars() {
if char == ' ' {
break;
}
ans.push(char);
}
ans
}
fn get_first_letter(sentence: &str) -> String {
sentence.chars().nth(0).unwrap().to_string()
}
fn get_index_of(sentence: &str, index: usize) -> String {
if let Some(c) = sentence.chars().nth(index) {
return c.to_string();
}
String::from("Not found")
}
Why Use &str
Instead of String
?
Rust has two main string types:
String
(Heap-allocated, mutable)&str
(Borrowed, slice reference, immutable)
Using &str
allows us to borrow data instead of moving it, which is essential for performance and memory safety.
Move vs. Borrowing in Rust
Move: When assigning a
String
to another variable, ownership transfers, making the original variable invalid.let s1 = String::from("Hello"); let s2 = s1; // Moves ownership, s1 is no longer valid
Borrowing (
&str
): Allows a function to reference data without taking ownership.fn print_str(data: &str) { println!("Data: {}", data); } let s = String::from("Rust"); print_str(&s); // Borrowing println!("Still valid: {}", s); // โ Works
Using borrowing (&str
) ensures functions can use strings without transferring ownership.
๐ Conclusion
In this blog, we covered:
Control Flow:
if
,else if
,else
, loops (loop
,while
,for
).Functions: How to define and call functions.
Ownership & Borrowing: Using
&str
to prevent data movement errors.
Rust's ownership model ensures memory safety without a garbage collectorโa game-changer for performance and reliability! ๐
๐ Follow and Explore!
๐ Follow Chiragkumar on GitHub and X:
You can clone and use my repo to test all the examples this blog covers!
๐ GitHub โ Star the repo and check out other cool projects! ๐
๐ฆ X (Twitter) โ Follow Chiragkumar to stay updated with my coding journey! ๐งโ๐ป
Happy coding! ๐
Subscribe to my newsletter
Read articles from CHIRAG KUMAR directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

CHIRAG KUMAR
CHIRAG KUMAR
Full stack Developer