Rust is supposedly a safe language, unlike C and its extensions. # Learn rust * https://doc.rust-lang.org/book/ -> 'the book' of rust * https://rust-book.cs.brown.edu/ -> version with quizzes and diagrams * https://tourofrust.com/ -> interactive lessons like freecodecamp; based on rust playground * https://rustlings.rust-lang.org/ -> rust exercises; useful with the book * https://doc.rust-lang.org/stable/rust-by-example/ -> runnable examples # Variables and types * Naming convention: `snake_case` * Variables are immutable by default * `let x = 5;` <-- here, `x` is a constant * prefix the variable name with `mut` to make it mutable: `let mut n = 10;` * Rust infers variable types. * Types can be specified at declaration: `let x: u8 = 12;` * Types can be appended to the end of a variable: `let x = 12u8;` * An interesting type - tuple: `let t = (16, 12, false, 3.1415);` * Access members with `t.0, t.1, ...` * Can be used to return multiple values from a function: `return (x, y);` * Destructure a tuple with `let (a, b, c) = tuple;` * here a, b, c will get the values of tuple.0, tuple.1, ... * Type conversion - `as`: ```rust let a = 5u8; let b = 16u32; let c = a as u32 + b; ``` * Constants must always have explicit types: `const PI: f32 = 3.14159;` * Arrays are fixed length collections of same-type elements: `let v: [i32; 4] = [1, 2, 3, 4];` # Printing to the screen * the `println!` macro is useful to print text to the screen. * to print variables put them inside curly brackets: `println!("x val: {x}");` * to print expressions, separate them by commas, like C's printf: `println!("x+2 is {}", x + 2);` # Conditionals and loops * No parentheses ```rust if a > b { println!("a gt b"); } else if b > a{ println!("b gt a"); ``` * Infinite loop with `loop` and `break`; * For loops with `for x in 0..5` and `for x in 0..=5` for iterating inclusively * Return values from a loop: ```rust let s = loop { x += 1; if x == 128 { break "reached 128!"; } }; println!("position: {}", s); ``` # switch -> match ```rust io::stdin().read_line(&mut n); match n { 5 => { println!("got 5"); } // mutiple options 10 | 15 | 20 => { println!("some multiple of 5"); } // bind match to variable n @ 21..=100 => { println!("found him: {}", n); } // obligatory default match _ => { println!("too far gone"); } } ``` # Functions This seems a lot like math notation (function add defined over i32 * i32 with values in i32, f(x,y)=x+y; ```rust fn add(x: i32, y: i32) -> i32 { return x + y; } ``` * You can drop the return statement from the end, making the last line `x+y` * This is the idiomatic way to return values at the end of a function in rust. * You can avoid polluting function scope with a scope block: ```rust fn main() { let a = 5; let x = { let a = 10; let b = 20; a + b } // will print "a: 5 x: 30" // b no longer exists here println!("a: {} x: {}", a, x); } ``` # Methods Methods are functions associated with a type. * Static methods - belong to a **type** - called with `::` operator - ex: `let s = String::from("cool string");` * Instance methods - belong to an **instance of a type** - called with `. (dot)` operator - ex: `let n = s.len();` (length of string) # Macros Macros in rust are like functions but they end with a `!`. See also -------- * https://rust.ipworkshop.ro/ -> IPWorkshop - rust * https://play.rust-lang.org/