Enjoy Day 2
We will need
vec
and array
to keep things organized as index.
Vec, iter, map, collect, into_iter, enumerate, unwrap
fn main() { // Create new `vec` and `array` of `&str`. let mut vec_of_foo = vec!["foo", "bar"]; // Say hi to vec! macro. let array_of_foo = ["foo", "bar"]; // Array of &str. println!("vec_of_foo: {vec_of_foo:#?}"); println!("array_of_foo: {array_of_foo:#?}"); // The different? vec_of_foo.push("baz"); // You can push more to Vec // 😱 Uncomment to see an error "no method named `push` found for array `[&str; 2]`". // FYI: `[&str; 2]` mean fixed array of &str usize 2. // 👍 Anyway fixed size is actually good for memory management, don't hate it! // array_of_foo.push("baz"); // You can't to fixed Array [&str; 2] // 1️⃣ Back to Vec, Let's iterate them. let hello_vec = vec_of_foo .iter() // Must `iter()` before you can map, filter,... .map(|e| format!("hello {e}")) // Say hi to `closure` |e| aka (e)=> in js. .collect::<Vec<_>>(); // `collect` inferred type from iterate. // 👆 `_` is inferred type (let compiler desire). println!("hello_vec: {hello_vec:#?}"); // 2️⃣ Do it again but with index. let indexed_vec = vec_of_foo .iter() .enumerate() // To access index we need `enumerate`. .map(|(i, e)| (i, e)) // Say hi to `Tuple` type. .collect::<Vec<(usize, &&str)>>(); // i is `usize`, e is &&str. println!("indexed_vec: {indexed_vec:#?}"); // 3️⃣ Do it again but `into_iter`. let into_iter_indexed_vec = vec_of_foo .into_iter() // `into_iter` instead of `iter` for `deref` (Wait what?). .enumerate() .map(|(i, e)| (i, e)) .collect::<Vec<(usize, &str)>>(); // e is just &str not &&str. // Or just `<Vec<_>>` if you lazy. println!("into_iter_indexed_vec: {into_iter_indexed_vec:#?}"); // `into_iter` is handy to pass value without borrow // but it can be problematic sometime if it has been borrowed by 1️⃣ and 2️⃣. // 😱 Uncomment this to see an error. // assert_eq!( // indexed_vec.first().unwrap().1, // FYI: avoid unwrap on prod. // &into_iter_indexed_vec.first().unwrap().1 // ); }
💡
::<>
is turbo fish 🐟💨 .
💡 Read more aboutiterate
here.
💡 If you crazy aboutiterate
do try Rust Iterator Cheat Sheet
So
iter
will make an auto borrow &
for us which is handy.
Anyway we can use into_iter
if we need to move instead of borrow with caution.
And also <Vec<_>>
is for lazy crab like us, nice!
🏂 Fun fact!
String
andVec
is allocated inheap
.
str
andarray
is allocated instack
.
HashMap, match, Option, Some, None, unwrap_or, panic
HashMap
is like Key/Value pair.
use std::collections::HashMap; // `use` aka `import` in js. // We talk about :: 👆 already, it's just a separator. fn main() { // Create new mutable hashmap let mut foo_hashmap = HashMap::new(); // Yet another :: here. // It's mutable so we can update it foo_hashmap.insert("name", "foo"); foo_hashmap.insert("age", "42"); // Or rather use HashMap::from for batch insert. let mut foo_hashmap = HashMap::from([ ("name", "foo"), ("age", "42"), ]); // Now use it let maybe_name: Option<&&str> = foo_hashmap.get("name"); // Will return `Option<&&str>`. // `match` aka `switch` in js. // Let's handle `Option<&&str>` which can be `Some` or `None`. match maybe_name { Some(name) => println!("1️⃣ hello {name}"), // Will print "hello foo". None => panic!("who!?"), // Will throw error with `panic!` macro. }; // Or handle with `unwrap_or`. let unwrapped_name = maybe_name.unwrap_or(&"who!?"); // And assign back by return after matched. let hi = match unwrapped_name { &"foo" => format!("2️⃣ hi! {unwrapped_name}"), // Will return unwrapped_name. _ => panic!("who!?"), // `_` aka `default` in js. }; println!("{hi}"); // Let's iterate and print it out. foo_hashmap .iter() // iter as usual, will use `for_each`. .for_each(|e| println!("{:?}", e)); // Just print, No need to collect. // Then we will use get👇 to borrow the value. let name = foo_hashmap.get("name").unwrap(); println!("name:{name:?}"); // Or take it by remove 👇. let age = foo_hashmap.remove("age").unwrap(); println!("age:{age:?}"); // 😱 So this will fail because we already remove it above. // let age = foo_hashmap.remove("age").unwrap(); }
💡
Option<T>
⎯⎯ unwrap →Some<T>
/None
whichT
is generic.
To know more about this try read more.
Don't be surprise if you found all this confusing. I did! But don't give up just yet!