From 869e68986aa8f69af6e7842260a68d1e5c6f796f Mon Sep 17 00:00:00 2001 From: Carlos Maiolino Date: Thu, 10 Jul 2025 22:24:20 +0200 Subject: Add a bunch of code Signed-off-by: Carlos Maiolino --- rust/.gitignore | 1 + rust/README.md | 1 + rust/arrays | Bin 0 -> 3982904 bytes rust/arrays.rs | 40 +++++++++ rust/borrowing.rs | 68 +++++++++++++++ rust/branches/Cargo.lock | 7 ++ rust/branches/Cargo.toml | 8 ++ rust/branches/src/main.rs | 26 ++++++ rust/compound.rs | 67 +++++++++++++++ rust/functions/Cargo.lock | 7 ++ rust/functions/Cargo.toml | 9 ++ rust/functions/src/main.rs | 19 ++++ rust/guessing_game/Cargo.lock | 75 ++++++++++++++++ rust/guessing_game/Cargo.toml | 9 ++ rust/guessing_game/src/main.rs | 36 ++++++++ rust/kaboom.rs | 9 ++ rust/kboom/Cargo.lock | 7 ++ rust/kboom/Cargo.toml | 8 ++ rust/kboom/src/main.rs | 9 ++ rust/loops/Cargo.lock | 7 ++ rust/loops/Cargo.toml | 8 ++ rust/loops/src/main.rs | 62 ++++++++++++++ rust/owner_ex.rs | 35 ++++++++ rust/ownership.rs | 74 ++++++++++++++++ rust/partial_move.rs | 49 +++++++++++ rust/random.rs | 119 ++++++++++++++++++++++++++ rust/refs_and_borrows/Cargo.lock | 7 ++ rust/refs_and_borrows/Cargo.toml | 8 ++ rust/refs_and_borrows/src/main.rs | 62 ++++++++++++++ rust/slices | Bin 0 -> 3977288 bytes rust/slices.rs | 39 +++++++++ rust/structs | Bin 0 -> 4008112 bytes rust/structs.rs | 25 ++++++ rust/tuples | Bin 0 -> 4009048 bytes rust/tuples.long-type-7360539414027225097.txt | 1 + rust/tuples.rs | 35 ++++++++ 36 files changed, 937 insertions(+) create mode 100644 rust/.gitignore create mode 100644 rust/README.md create mode 100755 rust/arrays create mode 100644 rust/arrays.rs create mode 100644 rust/borrowing.rs create mode 100644 rust/branches/Cargo.lock create mode 100644 rust/branches/Cargo.toml create mode 100644 rust/branches/src/main.rs create mode 100644 rust/compound.rs create mode 100644 rust/functions/Cargo.lock create mode 100644 rust/functions/Cargo.toml create mode 100644 rust/functions/src/main.rs create mode 100644 rust/guessing_game/Cargo.lock create mode 100644 rust/guessing_game/Cargo.toml create mode 100644 rust/guessing_game/src/main.rs create mode 100644 rust/kaboom.rs create mode 100644 rust/kboom/Cargo.lock create mode 100644 rust/kboom/Cargo.toml create mode 100644 rust/kboom/src/main.rs create mode 100644 rust/loops/Cargo.lock create mode 100644 rust/loops/Cargo.toml create mode 100644 rust/loops/src/main.rs create mode 100644 rust/owner_ex.rs create mode 100644 rust/ownership.rs create mode 100644 rust/partial_move.rs create mode 100644 rust/random.rs create mode 100644 rust/refs_and_borrows/Cargo.lock create mode 100644 rust/refs_and_borrows/Cargo.toml create mode 100644 rust/refs_and_borrows/src/main.rs create mode 100755 rust/slices create mode 100644 rust/slices.rs create mode 100755 rust/structs create mode 100644 rust/structs.rs create mode 100755 rust/tuples create mode 100644 rust/tuples.long-type-7360539414027225097.txt create mode 100644 rust/tuples.rs (limited to 'rust') diff --git a/rust/.gitignore b/rust/.gitignore new file mode 100644 index 0000000..901b6e6 --- /dev/null +++ b/rust/.gitignore @@ -0,0 +1 @@ +*/target/ diff --git a/rust/README.md b/rust/README.md new file mode 100644 index 0000000..c10ff5e --- /dev/null +++ b/rust/README.md @@ -0,0 +1 @@ +Collection of random rust programs for practice diff --git a/rust/arrays b/rust/arrays new file mode 100755 index 0000000..95fbd09 Binary files /dev/null and b/rust/arrays differ diff --git a/rust/arrays.rs b/rust/arrays.rs new file mode 100644 index 0000000..2e22751 --- /dev/null +++ b/rust/arrays.rs @@ -0,0 +1,40 @@ +// ARRAYS - similar than C +// +//array size must be known at compile time +// +// signature: [T; length] +// let var: [T; length] = foo + +fn main() { + let arr: [i32; 5] = [1, 2, 3, 4, 5]; + + // Implicit declaration: + let myarr = ['a', 'b', 'c']; + println!("{}", arr.len()); + + // Initialize all elements: [value, num of elements] + let auto_arr: [i32; 100] = [1; 100]; + + for c in arr { + print!("{} ", c); + } + + for c in myarr { + print!("{} ", c); + } + println!(""); + + println!("array sizes: arr {} myarr {}", std::mem::size_of_val(&arr), + std::mem::size_of_val(&myarr)); + + // Accessing specific elements in an array can be done via indexing or .get method + // .get method returns an Option, so we also need to use unwrap: + + let many: [i32; 10] = [1, 3, 4, 6, 8, 34, 60, 44, 94, 10]; + + // great, either many[3] or &many[3] works, shrug + println!("Via index: {} - Via get method: {}", + &many[3], many.get(6).unwrap()); +} + + diff --git a/rust/borrowing.rs b/rust/borrowing.rs new file mode 100644 index 0000000..89a10e9 --- /dev/null +++ b/rust/borrowing.rs @@ -0,0 +1,68 @@ +// Borrowing data +// +// We can access data created in another scope by borrowing it. +// +// Can be borrowed mutable or immutable. +// +// Borrowing Rules: +// +// - At any given time, you can have either a +// SINGLE MUTABLE reference or +// MANY IMMUTABLE references +// - References must always be valid +// + +// We can define references by +// +// Passing the reference to a var: let x = &var +// Using the ref keyworkd like: let ref x = var + +fn main() { + let s1 = String::from("hello"); + + // Pass a reference to String s1 + // this is a reference to the s1 not the string per se + let len: usize = calculate_length(& s1); + + // Mutable ref + let mut c = String::from("Howdy"); + + // Pass a mutable reference to change function + change(&mut c); + + // We can still use s1 here, because s1 is still the owner. + println!("The length of '{}' is {}.", s1, len); + println!("{}", c); + + print_pointer(); +} + + +// The function receives a 'reference' to a String +fn calculate_length(s: & String) -> usize { + return s.len(); +} + +fn change(c: &mut String) { + c.push_str(" partner"); +} + +fn print_pointer() { + let x: i32 = 5; + + let p: &i32 = &x; + + println!("PTR is: {:p}", p); +} +// This function is just an example of 2nd rule violation +// It returns a reference to a string that will run out of +// scope once the function returns. +// Thanks to that, we return a dangling pointer. Rustc won't +// let us compile it. + +// Could be fixed by returning the String data itself +//fn dangling_ptr() -> &String { +// let s = String::from("howdy"); +// +// return &s; +//} diff --git a/rust/branches/Cargo.lock b/rust/branches/Cargo.lock new file mode 100644 index 0000000..b420e22 --- /dev/null +++ b/rust/branches/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "branches" +version = "0.1.0" diff --git a/rust/branches/Cargo.toml b/rust/branches/Cargo.toml new file mode 100644 index 0000000..6934aa4 --- /dev/null +++ b/rust/branches/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "branches" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/rust/branches/src/main.rs b/rust/branches/src/main.rs new file mode 100644 index 0000000..450f526 --- /dev/null +++ b/rust/branches/src/main.rs @@ -0,0 +1,26 @@ +fn main() { + let number = 6; + + if number < 5 { + println!("condition was true"); + } else { + println!("condition was false"); + } + + if number % 4 == 0 { + println!("Divisible by 4"); + } else if number % 3 == 0 { + println!("Divisible by 3"); + } else if number % 2 ==0 { + println!("Divisible by 2"); + } else { + println!("Shit hit the fan"); + } + + let condition =true; + let x = if condition { 5 } else { 6 }; + println!("The value of number is: {x}"); + + // This code Kabooms + // let foo = if condition { 6 } else { "seven" }; +} diff --git a/rust/compound.rs b/rust/compound.rs new file mode 100644 index 0000000..5a8114f --- /dev/null +++ b/rust/compound.rs @@ -0,0 +1,67 @@ +// Compound types +// +// Types composed of another types + +// String vs &str +// String - string slices + +// String: heap allocated string type - NOT NULL TERMINATED +// (ptr, len, capacity) +// &str: immutable sequence of UTF-8 bytes in memory +// (ptr, len) +// &str - more lightweight and efficient +// +// String Literal: compile time known sequence of UTF-8 bytes + +fn main() { + let s = String::from("Howdy partner"); + + let hello: &str = &s[0..5]; + let world: &str = &s[6..13]; + +// Wow, suuuper safe +// let world: &str = &s[6..14]; + + println!("{} {}", hello, world); + compound(); + string_playground(); + concatenate(); +} + +fn compound() { + let s: Box = "Howdy partner".into(); + greetings(&s); + + // We could also just not use a box here and create a slice. + // let s: &str = "Howdy partner"; + // greetings(s); +} + +fn greetings(s: &str) { + println!("{}", s); +} + +fn string_playground() { + let mut s = String::from(""); + s.push_str("hello, world"); + s.push('!'); + + println!("Success"); +} + +fn concatenate() { + let s1: String = String::from("howdy,"); + let s2: String = String::from("partner"); + + // you can concatenate a String + &str but you can't concatenate 2 Strings + // This consumes the string, and the ownership of s1 is transferred to s3 + // This likely just push s2 into s1. + + // Two ways of converting s2 to str: + // using .as_str() method +// let s3: String = s1 + s2.as_str(); + // passing a reference to &s2 + let s3: String = s1 + &s2; + + println!("{}", s3); +} diff --git a/rust/functions/Cargo.lock b/rust/functions/Cargo.lock new file mode 100644 index 0000000..82f83a1 --- /dev/null +++ b/rust/functions/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "functions" +version = "0.1.0" diff --git a/rust/functions/Cargo.toml b/rust/functions/Cargo.toml new file mode 100644 index 0000000..046807f --- /dev/null +++ b/rust/functions/Cargo.toml @@ -0,0 +1,9 @@ +workspace = { members = ["branches"] } +[package] +name = "functions" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/rust/functions/src/main.rs b/rust/functions/src/main.rs new file mode 100644 index 0000000..d246d2c --- /dev/null +++ b/rust/functions/src/main.rs @@ -0,0 +1,19 @@ +fn main() { + println!("Hello, world!"); + another_function(5, 'Y'); + println!("FOO: {}", foo()); + println!("PlusOne: {}", plus_one(5)); +} + +fn another_function(x:i32, y:char) { + println!("The value of x is: {x} and y is: {y}"); +} + +// This kaboom +fn foo() -> i32 { + 3+5; +} + +fn plus_one(x: i32) -> i32 { + x + 1 +} diff --git a/rust/guessing_game/Cargo.lock b/rust/guessing_game/Cargo.lock new file mode 100644 index 0000000..35b36c9 --- /dev/null +++ b/rust/guessing_game/Cargo.lock @@ -0,0 +1,75 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand", +] + +[[package]] +name = "libc" +version = "0.2.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" diff --git a/rust/guessing_game/Cargo.toml b/rust/guessing_game/Cargo.toml new file mode 100644 index 0000000..7eda67a --- /dev/null +++ b/rust/guessing_game/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.8.5" diff --git a/rust/guessing_game/src/main.rs b/rust/guessing_game/src/main.rs new file mode 100644 index 0000000..7c6fea3 --- /dev/null +++ b/rust/guessing_game/src/main.rs @@ -0,0 +1,36 @@ +use rand::Rng; +use std::cmp::Ordering; +use std::io; + +fn main() { + println!("Guess the number!"); + + let secret_number = rand::thread_rng().gen_range(1..=100); + + loop { + println!("Please input your guess."); + + let mut guess = String::new(); + + io::stdin() + .read_line(&mut guess) // Returns a 'Result' type + .expect("Failed to read line"); + + // /- Returns a Result type + let guess: u32 = match guess.trim().parse() { + Ok(num) => num, + Err(_) => continue, + }; + + println!("You guessed: {guess}"); + + match guess.cmp(&secret_number) { + Ordering::Less => println!("Too small!"), + Ordering::Greater => println!("Too big!"), + Ordering::Equal => { + println!("You win!"); + break; + } // Code block executed if match hits ::Equal + }; + } +} diff --git a/rust/kaboom.rs b/rust/kaboom.rs new file mode 100644 index 0000000..28c740d --- /dev/null +++ b/rust/kaboom.rs @@ -0,0 +1,9 @@ +fn main() { + + let s: String = String::from("Howdy partner"); + + let s: &str = &s; + let i: usize = 5; + + println!("{}", &s[0..i]); +} diff --git a/rust/kboom/Cargo.lock b/rust/kboom/Cargo.lock new file mode 100644 index 0000000..0148ef8 --- /dev/null +++ b/rust/kboom/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "kboom" +version = "0.1.0" diff --git a/rust/kboom/Cargo.toml b/rust/kboom/Cargo.toml new file mode 100644 index 0000000..8a88b48 --- /dev/null +++ b/rust/kboom/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "kboom" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/rust/kboom/src/main.rs b/rust/kboom/src/main.rs new file mode 100644 index 0000000..1cb2765 --- /dev/null +++ b/rust/kboom/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + + let mut x:u8 = 10; + let i = 10; + loop { + x += i; + println!("Hello, world {x}"); + } +} diff --git a/rust/loops/Cargo.lock b/rust/loops/Cargo.lock new file mode 100644 index 0000000..4d2ad7f --- /dev/null +++ b/rust/loops/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "loops" +version = "0.1.0" diff --git a/rust/loops/Cargo.toml b/rust/loops/Cargo.toml new file mode 100644 index 0000000..0d5dad5 --- /dev/null +++ b/rust/loops/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "loops" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/rust/loops/src/main.rs b/rust/loops/src/main.rs new file mode 100644 index 0000000..2458311 --- /dev/null +++ b/rust/loops/src/main.rs @@ -0,0 +1,62 @@ +fn main() { + let mut counter = 0; + + let result = loop { + counter += 1; + + if counter == 10 { + // loop {} is an expression and can return values, this is sick. + break counter * 2; + } + }; + + println!("The result is {result}"); + + let mut count = 0; + 'counting_up: loop { // Loop label 'counting_up + println!("count = {count}"); + let mut remaining = 10; + + loop { + println!("remaining = {remaining}"); + if remaining == 9 { + break; + } + + if count == 2 { + break 'counting_up; // Break the outter loop + } + remaining -= 1; + } + + count += 1; + } + println!("End count = {count}"); + + let mut number = 3; + + while number != 0 { + println!("Number: {number}"); + number -= 1; + } + println!("While is gone"); + + let a = [10, 20, 30, 40, 50]; + let mut index = 0; + + while index < 5 { + println!("{}", a[index]); + index += 1; + } + + // Using a for loop + for element in a { + println!("the value is: {element}"); + } + + // Range - .rev == reverse + for number in (1..4).rev() { + println!("{number}"); + } + +} diff --git a/rust/owner_ex.rs b/rust/owner_ex.rs new file mode 100644 index 0000000..f76a783 --- /dev/null +++ b/rust/owner_ex.rs @@ -0,0 +1,35 @@ +fn main() { + + // This is interesting... + // &str annotate we are using a string literal, not creating + // a string at run time. + // It means the size of the tuple is known at compilation time. + let x: (i32, i32, (), &str) = (1, 2, (), "hello"); + + // Because we know the tuple size at compilation time, (and likely + // because it's allocated on the stack, we can simply copy it here. + let y: (i32, i32, (), &str) = x; + + println!("{:?}, {:?}", x, y); + + // s oritinally immutable + let s: String = String::from("hello, "); + + // Transferring ownership can be done to a mutable variable + let mut s1 = s; + + s1.push_str("world"); + + println!("{}", s1); + + // x now is a pointer to the heap memory + let x: Box = Box::new(5); + + // y is also a pointer + let mut y: Box = Box::new(1); + + // Dereferencing Y address + *y = 4; + + assert_eq!(*x, 5); +} diff --git a/rust/ownership.rs b/rust/ownership.rs new file mode 100644 index 0000000..3a96743 --- /dev/null +++ b/rust/ownership.rs @@ -0,0 +1,74 @@ +// Rules of ownership: +// +// 1 - each value has an owner +// 2 - only one owner allowed +// 3 - if owner goes out of scope, value will be freed +// +// Scopes: Global, local -> Similar to C + +fn main() -> () { + + let h = "Hello"; // s is the owner + let s = get_string(); + +// let s2 = s; // This only copies the pointer value, not the + // String data type + // + // This essentially violates the ownership rule of + // a single owner. + // Because of that, rust compiler drops the ownership + // of the original variable 's', only s2 owns the pointer + // now. + + let s2 = s.clone(); // Deep copy String s + + println!("{}", h); + + println!("{}", s2); + + println!("{}", s); // generates an error due to ownership if .clone ain't used + + + // Transferring ownership + + take_ownership(s); // 's' value is moved to the function. From now on, 's' is + // no longer valid here. + +// println!("{}", s); // KABOOM + + // give_ownership allocate and return us a + // String type, giving s3 ownership of the + // allocated String. + // s3 belongs to this scope now. + let s3 = give_ownership(); + + // Sending and getting ownership back + + let s5 = String::from("This is mine"); + let s5 = give_me_back(s5); // I'm shadowing s5 here, but I could have used + // something else + + println!("{} {}", s3, s5); + +} // s - only valid to here + +fn give_me_back(s: String) -> String { + + return s; +} + +fn give_ownership() -> String { + + // The ownership of the String allocated here + // will be transferred to the caller. + return String::from("Jumento celestino"); +} +fn take_ownership(s: String) { + println!("Ownership transfer completed. \n{}", s); + + // Reaching end of this scope will free 's' +} + +fn get_string() -> String { + return String::from("Ronaldo"); +} diff --git a/rust/partial_move.rs b/rust/partial_move.rs new file mode 100644 index 0000000..84fb163 --- /dev/null +++ b/rust/partial_move.rs @@ -0,0 +1,49 @@ +fn main() { + #[derive(Debug)] + struct Person { + name: String, + age: Box, + } + + let alice: Person = Person { + name: String::from("Alice"), + age: Box::new(20), + }; + + println!("{} {}", alice.name, *alice.age); + + // Destructure the fields of the variable 'alice' + // + // Now we've got two new variables, name and age. + // + // Notice the 'ref' keyword here, meaning 'age', meaning + // 'age' is just a reference to the data. + // 'name' though, will be moved here, and this 'name' var + // will be the new owner of this data. + // + let Person {name, ref age} = alice; + + // From now on, 'alice' Struct is not anymore, it has no + // ownership of its data. + // Its data has been dismembered and it's now owned by + // 'name' and 'age' + println!("Name: {} - Age: {}", name, *age); + + // Destructuring tuples + + // Tuple containing two strings + let t: (String, String) = ((String::from("Ronaldo")), (String::from("Brilha Muito"))); + + let s: String = t.0; + + println!("{} {}", s, t.1); + + // I can't access t.0 directly anymore as the string's ownership has been moved to 's' + // println!("{}", t.0); // Kaboom + + let t2: (String, String) = ((String::from("Foo")), (String::from("Bar"))); + + let (new_t1, new_t2): (String, String) = t2.clone(); + + println!("STR1: {} STR2: {}", new_t1, new_t2); +} diff --git a/rust/random.rs b/rust/random.rs new file mode 100644 index 0000000..42a8f94 --- /dev/null +++ b/rust/random.rs @@ -0,0 +1,119 @@ +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(); +} diff --git a/rust/refs_and_borrows/Cargo.lock b/rust/refs_and_borrows/Cargo.lock new file mode 100644 index 0000000..cf9d7bd --- /dev/null +++ b/rust/refs_and_borrows/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "refs_and_borrows" +version = "0.1.0" diff --git a/rust/refs_and_borrows/Cargo.toml b/rust/refs_and_borrows/Cargo.toml new file mode 100644 index 0000000..76c4f89 --- /dev/null +++ b/rust/refs_and_borrows/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "refs_and_borrows" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/rust/refs_and_borrows/src/main.rs b/rust/refs_and_borrows/src/main.rs new file mode 100644 index 0000000..212372b --- /dev/null +++ b/rust/refs_and_borrows/src/main.rs @@ -0,0 +1,62 @@ +fn main() { + let m1 = String::from("Hello"); + let m2 = String::from("world"); + + // Borrow m1 and m2 references to greet(), instead of passing ownership + greet(&m1, &m2); + let s = format!("{} {}", m1, m2); + println!("{s}"); + +// fing_it(); +// aliasing_bonanza(); +// mutable_bonanza(); + flow_me(); +} + +// g1 is a reference that points to m1 on the stack, and m1 is a String +// containing a box, pointing to "Hello" string on the heap. +fn greet(g1: &String, g2: &String) -> () { + println!("Greet: {}, {}", *g1, *g2); +} + +fn fing_it() -> () { + let mut x: Box = Box::new(1); + let _a:i32 = *x; + *x += 1; + + let ref1: Box = Box::new(-5); + + println!("This is sparta: {}", i32::abs(*ref1)); +} + +/* +fn aliasing_bonanza() -> () { + let mut v: Vec = vec![10, 20, 30]; + let num: &i32 = &v[2]; + v.push(40); + + println!("{:?}", *num) +} +*/ +fn mutable_bonanza() -> () { + let mut v: Vec = vec![10, 20, 30]; + + // let mut makes the VAR mutable, i.e. it can be reassigned + // let :&mut i32 = &mut foo creates an IMMUTABLE that points to a + // mutable memory + + let num: &mut i32 = &mut v[2]; + let num2: &i32 = num; + + println!("Index 2 == {}", *num2); +} + +// Yes, moving { to the next line on purpose +fn flow_me(strings: &Vec, default: &String) -> &String +{ + if strings.len() > 0 { + &strings[0] + } else { + default + } +} diff --git a/rust/slices b/rust/slices new file mode 100755 index 0000000..0824aee Binary files /dev/null and b/rust/slices differ diff --git a/rust/slices.rs b/rust/slices.rs new file mode 100644 index 0000000..096fe56 --- /dev/null +++ b/rust/slices.rs @@ -0,0 +1,39 @@ +// SLICES +// +// Contiguous sequence of elements in a collection +// enables us to borrow part of a collection without +// taking ownership of the whole thing +// +// can be created from arrays, vectors, strings and +// any other collection implementing the 'Deref' trait +// +// slices length are not known at compile time +// +// Type signature: &[T] + +fn main() { + + let a: [i32; 5] = [36234689, 2, 3, 4, 5]; + + // correct way to annotate slice types + let slice: &[i32] = &a[..4]; + + println!("{:?}", slice); + + // Slices are two-words object (occupies 2-words in memory). + // first word is the data pointer, second is the slice length: + let s2: &[i32] = &a[..5]; + + // If this is a 64-bit machine, this should return 16 bytes. + // as we have 64-bit words. + println!("Slice size: {} bytes", std::mem::size_of_val(&s2)); + + // Slices are byte indexed, the index '[foo]' is actually a byte + // number, not member number. + // + // ^ I don't think this is correct, but the course made it work + // with strings, perhaps it is only valid for string type, shrug. + let s3: &[i32] = &a[0..1]; + let b: i32 = s3[0]; + println!("{:?}", b); +} diff --git a/rust/structs b/rust/structs new file mode 100755 index 0000000..97ec88c Binary files /dev/null and b/rust/structs differ diff --git a/rust/structs.rs b/rust/structs.rs new file mode 100644 index 0000000..0d0ac64 --- /dev/null +++ b/rust/structs.rs @@ -0,0 +1,25 @@ +struct Student { + name: String, + age: u8, + gradeA: f64, + gradeB: f64, +} + +fn main() { + let mut student1 = Student { + name: String::from("Tiao Barbosa"), + age: 59, + gradeA: 5.9, + gradeB: 6.5, + }; + + println!("Name: {} Age: {} GradeA: {} GradeB: {}", + student1.name, student1.age, + student1.gradeA, student1.gradeB); + + student1.name = String::from("Ronaldo do curintia"); + println!("Name: {} Age: {} GradeA: {} GradeB: {}", + student1.name, student1.age, + student1.gradeA, student1.gradeB); + +} diff --git a/rust/tuples b/rust/tuples new file mode 100755 index 0000000..e6b710f Binary files /dev/null and b/rust/tuples differ diff --git a/rust/tuples.long-type-7360539414027225097.txt b/rust/tuples.long-type-7360539414027225097.txt new file mode 100644 index 0000000..86d45ea --- /dev/null +++ b/rust/tuples.long-type-7360539414027225097.txt @@ -0,0 +1 @@ +({integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}) diff --git a/rust/tuples.rs b/rust/tuples.rs new file mode 100644 index 0000000..2ea6c19 --- /dev/null +++ b/rust/tuples.rs @@ -0,0 +1,35 @@ +// Tuples are compund values + +fn main() { + let _t0: (u8, i16) = (0, -1); + + // Tuples can be nested + let _t1: (u8, (i32, u16)) = (2, (-9, 99)); + + println!("{:?}", _t1); + + // Long tuples can't be printed: + //let long_tuple = (1,2,3,4,5,6,7,8,9,10,11,12,13); + //println!("{:?}", long_tuple); + + // Tuples can be destructured + let tup: (i32, f64, &str) = (1, 5.3, "corno"); + + let (x, y, z) = tup; + + println!("{} {} {}", x,y,z ); + + let (x, y, z) = (9, 10, 11); + println!("{} {} {}", x,y,z ); + + let (sum, mul) = sum_mul((3, 5)); + + println!("{} {}",sum, mul); +} + +// Tuples can be passed as function arguments +// and used as return values + +fn sum_mul(nums: (i32, i32)) -> (i32, i32) { + (nums.0 + nums.1, nums.0 * nums.1) +} -- cgit v1.2.3