// run with `cargo run` const SOMETHING: f32 = 5.78; fn main() { // use `let` to declare variables // default type for integer is i32 let x = 3; let y = 4; // use println! to print the values println!("the value of x is {x} and y is {y}"); // -- types // some types can be inferred by the compiler (see above) // sometimes, you want to provide a specific type let z: i32 = 3; // signed integers, 32 bits println!("the value of z is {z}"); let z: i64 = 5; // signed integers, 64 bits println!("the value of z is {z}"); let z: i8 = 5; // signed integers, 8 bits // unsigned integers starts with a `u` let z: u8 = 5; // *un*signed integers, 8 bits let z: u128 = 5; // *un*signed integers, 128 bits // addition let a: i32 = 3; let b: i64 = 6; let c = a + 5; // casting to other types let c = a as i64 + b; // careful, as is too powerfull let c = a + b as i32; // careful, as is too powerfull // let c = a + i32::from(b); // KO let c = i64::from(a) + b; // -- mutability let mut c = i64::from(a) + b; c += 3; // or `c = c + 3;` println!("the value of c is now {c}"); // -- constants println!("the `something` constant is {SOMETHING}"); // -- strings let string_one: String = String::from("one"); let mut string_bytes = string_one.as_bytes(); { // `string_two` will be discarded at the end of the scope let string_two = String::from("two"); // string_bytes = string_two.as_bytes(); // does not compile } // string_two does not exists anymore // println!("{}", string_two); // error println!("the string is {}", string_one); println!("the bytes of the string are {:?}", string_bytes); // println!("{:?}", string_bytes[4]); // KO, out of bounds }