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! π
Here's a closing section you can use for your technical blog:
π Follow and Explore!
π Follow Chiragkumar on GitHub and X:
You can clone and use my repo to test all the examples covered in this blog!
π GitHub β Star the repo and check out other cool projects! π
π¦ X (Twitter) β Follow Chiragkumar to stay updated with my coding journey! π§βπ»
Happy coding! π
Top comments (0)