<100 subscribers
Rust is like that overprotective friend who wonât let you borrow their car without a full background check. Itâs all about safetyâespecially when it comes to control flow and ownership. But donât worry! This Monday with Rust over Polkadot its time to learn all of it with some fun and increasingly complex code examples. Buckle up!
Rustâs if
statements work like they do in most languages, but with a little twistâno parentheses required!
fn main() {
let temperature = 30;
if temperature > 25 {
println!("It's hot! Time for some ice cream! ");
} else {
println!(" it's manageable.");
}
}
Now, letâs spice things up with a match
statement, Rustâs supercharged version of switch
.
fn main() {
let weather = "rainy";
match weather {
"sunny" => println!("Break out the sunglasses! "),
"rainy" => println!("Better bring an umbrella! "),
"snowy" => println!("Time to build a snowman! "),
_ => println!("Hmm... I have no idea what to do."),
}
}
With match
, Rust makes sure you cover all cases. No sneaky bugs here! đ
Rust has three main loops: for
, while
, and loop
. Letâs level up our complexity.
fn main() {
let snacks = ["apple", "banana", "chocolate"];
for snack in snacks.iter() {
println!("Eating: {}", snack);
}
}
fn main() {
let mut fuel = 3;
while fuel > 0 {
println!("Vroom! Fuel left: {}", fuel);
fuel -= 1;
}
println!("Out of fuel! Time to refuel. ");
}
fn main() {
let mut counter = 0;
loop {
println!("Counting: {}", counter);
counter += 1;
if counter == 5 {
println!("Stopping at 5! ");
break;
}
}
}
Rust has strict ownership rules, making sure memory safety is a top priority.
fn main() {
let snack = String::from(" Donut");
let snack2 = snack; // Ownership moves here!
// println!("First snack: {}", snack); // â ERROR! `snack` is gone!
println!("Second snack: {}", snack2); // â
Works!
}
Rust doesnât allow snack
to be used after itâs movedâjust like a jealous toddler who wonât share their toys. đ§¸
Rust lets you borrow a variable instead of moving it, but you must follow strict borrowing rules!
fn main() {
let snack = String::from(" Cookie");
eat_snack(&snack); // Borrowing instead of moving
println!("Still have my snack: {}", snack); // â
Works fine!
}
fn eat_snack(snack: &String) {
println!("Eating: {}", snack);
}
đ Rule: You can have one mutable reference OR multiple immutable references, but not both at the same time.
fn main() {
let mut drink = String::from("Soda");
let drink_ref1 = &drink;
let drink_ref2 = &drink;
// let drink_mut = &mut drink; // â ERROR! Cannot mix mutable and immutable references.
println!("{} and {}", drink_ref1, drink_ref2); // â
Works fine!
}
Rust ensures references live long enough to be useful. Hereâs an example with an explicit lifetime annotation:
fn main() {
let snack = String::from("Pizza");
let result;
{
let topping = String::from("Cheese");
result = best_combo(&snack, &topping);
println!("{}", result);
} // `topping` goes out of scope here
// println!("Still have: {}", result); // â ERROR! `topping` is gone!
}
fn best_combo<'a>(food: &'a String, topping: &'a String) -> String {
format!("Best combo: {} + {}", food, topping)
}
Rust makes sure result
doesnât outlive the topping
. If it did, we'd have a dangling reference (aka ghost memory! đť).
Mastering control flow and ownership is like learning how to drive a Formula 1 carâexciting but with strict safety rules. đ¨
Use if/else/match to make decisions.
Use for/while/loop to repeat tasks.
Understand ownership to avoid Rust's strict errors.
Borrow responsibly to keep your variables alive.
Use lifetimes to ensure references donât go out of scope.
Congrats, Rustacean! đŚ Keep coding, keep laughing, and may the rust be with you! đ