rust
Table of Contents
Rust
Variables
fn main() { let x = 5; // Immutable i32 (default) let mut y = 5.0; // Mutable f32 (default) y += 1; let y = 6; // Shadowing is fine // Constants need explicit type const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3; let f: bool = false; // Boolean let c: char = 'z'; // Character let tup: (i32, f64, u8) = (500, 6.4, 1); // Tuple let a: [i32; 5] = [1, 2, 3, 4, 5]; // Array }
Control flow
if number < 5 { println!("condition was true"); } else if number % 3 == 0 { println!("number is divisible by 3"); } else { println!("condition was false"); }
let mut count = 0; 'counting_up: loop { println!("count = {count}"); let mut remaining = 10; loop { println!("remaining = {remaining}"); if remaining == 9 { break; } if count == 2 { break 'counting_up; } remaining -= 1; } count += 1; }
while number != 0 { println!("{number}!"); number -= 1; }
let a = [10, 20, 30, 40, 50]; for element in a { println!("the value is: {element}"); }
References and Borrowing
let mut x: Box<i32> = Box::new(1); let a: i32 = *x; // *x reads the heap value, so a = 1 *x += 1; // *x on the left-side modifies the heap value, // so x points to the value 2 let r1: &Box<i32> = &x; // r1 points to x on the stack let b: i32 = **r1; // two dereferences get us to the heap value let r2: &i32 = &*x; // r2 points to the heap value directly let c: i32 = *r2; // so only one dereference is needed to read it // Mutable reference let mut v: Vec<i32> = vec![1, 2, 3]; let num: &mut i32 = &mut v[2]; *num += 1;
Struct methods
Functions in a struct that have self as parameter is called method and it is an associated function.
Associated functions that don't have self as parameters can be used as for example constructors. But they are not called methods.
struct Rectangle { width: u32, height: u32, } impl Rectangle { fn area(&self) -> u32 { self.width * self.height } fn can_hold(&self, other: &Rectangle) -> bool { self.width > other.width && self.height > other.height } fn square(size: u32) -> Self { Self { width: size, height: size, } } } fn main() { let a : Rectangle::square(5); let b : Rectangle { width: 1, height: 2, } println!("Can a fit in b? {}", b.can_hold(&a)); }
Debug attribute and println!
#[derive(Debug)] struct Rectangle { width: u32, height: u32, } fn main() { let rect1 = Rectangle { width: 30, height: 50, }; println!("rect1 is {:?}", rect1); // Or with pretty print :#? println!("rect1 is {:#?}", rect1); }
Using dbg! macro in struct assignment can be done as dbg! returns ownership of the expression value.
#[derive(Debug)] struct Rectangle { width: u32, height: u32, } fn main() { let scale = 2; let rect1 = Rectangle { width: dbg!(30 * scale), height: 50, }; dbg!(&rect1); }
Enums
enum IpAddrKind { V4, V6, } fn main() { let four = IpAddrKind::V4; let six: IpAddrKind = IpAddrKind::V6; // Explicit type }
Enums can have different content for their different enumerations.
enum Message { Quit, Move { x: i32, y: i32 }, Write(String), ChangeColor(i32, i32, i32), }
They can also have functions
enum Message { Quit, Move { x: i32, y: i32 }, Write(String), ChangeColor(i32, i32, i32), } impl Message { fn call(&self) { // method body would be defined here } } let m = Message::Write(String::from("hello")); m.call();
There is the special Option type available in the standard library std::option::Option
enum Option<T> { None, Some(T), }
let some_number = Some(5); let some_char = Some('e'); let absent_number: Option<i32> = None;
Matching
enum UsState { Alabama, Alaska, // --snip-- } enum Coin { Penny, Nickel, Dime, Quarter(UsState), } fn value_in_cents(coin: Coin) -> u8 { match coin { Coin::Penny => 1, Coin::Nickel => 5, Coin::Dime => 10, Coin::Quarter(state) => { println!("State quarter from {:?}!", state); 25 } } }
Can match integers as well
let dice_roll = 9; match dice_roll { 3 => add_fancy_hat(), 7 => remove_fancy_hat(), other => move_player(other), } fn add_fancy_hat() {} fn remove_fancy_hat() {} fn move_player(num_spaces: u8) {}
rust.txt · Last modified: 2024/07/11 20:46 by utedass
