fn print_char(c: char) { println!("Char: {}", c); } // Unit type playground function // Implicitly returns a unit type fn implicitly_ret_unit() -> () { println!("Returning a ()"); } fn main() { println!("Hello World"); // Char bool unit // // char type in rust is 4 bytes, so it can hold unicode let c1: char = 'a'; println!("Size: {}", size_of_val(&c1)); print_char(c1); let _f: bool = false; if !_f { print_char('F'); } // UNIT ype // // Unit does not hold any value, returned implicitly // usually when a function returns nothing let _v: () = (); // A unit type is represented as an empty tuple //let v: (i32, i32) = (2, 3); assert_eq!(_v, implicitly_ret_unit()); // Unit type size is 0 println!("Size of a unit type: {}", size_of_val(&_v)); // Statement vs Expression // // Statement: instruction perform some action but no value is produced // // Expression: Evaluate to a resultant value let x: u32 = 5_u32; // Initializing y with the value of a whole expression. // This is considered an expression because it results in a // value. // The variable assignment though is a statement let y: u32 = { let x_squared = x * x; let x_cube = x_squared * x; // This is the most confusing part.... // By ommitting the ; here, the result evaluation will be // assigned to y. x_cube + x_squared + x }; println!("Expression Y: {}", y); // Variable is assigned to a unit type: // Because the expression ends in a semicolon, there is no // value produced by it, to the resulting 'value' is the unit // type let _z = { 2 * x; }; println!("What is Z? - {:?}", _z); let x = 1; let y = { let mut x = 1; // x += 2 // Variable assignments are statements x += 2; // and produces a unit (nothing) value x // A single variable expression will // produce the variable value }; println!("Type of y: {:?}", y); match_me(2, false); } // Functions must always annotate types for arguments fn sum(x: i32, y: i32) -> i32 { // x + y; // Would return a unit type x + y // Returns an i32 } // Diverging functions: Never return to the caller // Panics, infinite loops, exiting, etc fn never_return() -> ! { // ! return type means this is a diverging function // unimplemented!(); // interesting macros return todo!(); } fn match_me(tp: u8, b: bool) -> Option { match tp { 1 => {println!("TP is 1");} 2 => {println!("TP is 2");} _ => {println!("TP is garbage");} }; let _v = match b { true => 1, false => { println!("success"); panic!("Panic Me"); } }; return never_return(); }