diff --git a/src/main.rs b/src/main.rs index 3047a9e..e243a8a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ fn main() { chapter_5(); chapter_6(); chapter_7(); + chapter_8(); } fn chapter_1() { @@ -825,3 +826,173 @@ use foo::{ bar::{self, Foo}, baz::{*, quux::Bar}, }; + +fn chapter_8() { + println!("Chapter 8: Common collections"); + vectors(); + strings(); + hash_maps(); + + println!("Exercice time 😺"); + + println!(); +} + +fn vectors() { + println!("Vectors"); + let mut v = vec![1, 2, 3]; + v.push(4); + + { + // let does_not_exist = &v[100]; // panic + let does_not_exist = v.get(100); // Option<&T> + println!("We can get a vector value with `&v[i]` or `v.get(i)`: {:?}", does_not_exist); + } + + for i in &v { + println!("{}", i); + } + + for i in &mut v { + *i += 50; + } + + for i in &v { + println!("{}", i); + } + + #[derive(Debug)] + enum SpreadsheetCell { + Int(i32), + Float(f64), + Text(String), + } + let row = vec![ + SpreadsheetCell::Int(3), + SpreadsheetCell::Text(String::from("blue")), + SpreadsheetCell::Float(13.37), + ]; + + println!("To have multiples types inside a vector we should use an enum: {:?}.", row); + + println!(); +} + +fn strings() { + let hello = String::from("السلام عليكم"); + println!("Hello: {}", hello); + let hello = String::from("Dobrý den"); + println!("Hello: {}", hello); + let hello = String::from("Hello"); + println!("Hello: {}", hello); + let hello = String::from("שָׁלוֹם"); + println!("Hello: {}", hello); + let hello = String::from("नमस्ते"); + println!("Hello: {}", hello); + let hello = String::from("こんにちは"); + println!("Hello: {}", hello); + let hello = String::from("안녕하세요"); + println!("Hello: {}", hello); + let hello = String::from("你好"); + println!("Hello: {}", hello); + let hello = String::from("Olá"); + println!("Hello: {}", hello); + let hello = String::from("Здравствуйте"); + println!("Hello: {}", hello); + let hello = String::from("Hola"); + println!("Hello: {}", hello); + + let s1 = String::from("Hello, "); + let s2 = String::from("world!"); + let s3 = s1 + &s2; + println!("s1 is moved and not usable anymore, s2: {}, s3: {}", /*s1, */s2, s3); + let s2 = String::from("tac"); + + let s1 = String::from("tic"); + let s3 = String::from("toe"); + + let s = s1 + "-" + &s2 + "-" + &s3; + println!("s: {}", s); + + let s1 = String::from("tic"); // s1 was moved because of the `+` operator + + let s = format!("{}-{}-{}", s1, s2, s3); + println!("s: {}, s1 {}, s2 {}, s3 {}", s, s1, s2, s3); // here no String is moved + + println!("We cannot use index on Strings but we can refer to a range."); + println!("But we should be carefull with the ranges to not split a 2byte unicode char."); + + let hindi_2bytes_with_modifiers = "नमस्ते"; + + println!("Individuals bytes:"); + for b in hindi_2bytes_with_modifiers.bytes() { + println!("{}", b); + } + + println!("Individuals UTF-8 chars. Note the modifier (accents, ...) may be separated from the naked character."); + for c in hindi_2bytes_with_modifiers.chars() { + println!("{}", c); + } + + println!("If we want the human characteres insteads of the UTF-8 ones -> https://crates.io/"); + + println!(); +} + +fn hash_maps() { + use std::collections::HashMap; + + let mut scores = HashMap::new(); + + scores.insert(String::from("Blue"), 10); + scores.insert(String::from("Yellow"), 50); + + println!("Scores: {:?}", scores); + + let teams = vec![String::from("Blue"), String::from("Yellow")]; + let initial_scores = vec![10, 50]; + + let scores_tuple = teams.iter().zip(initial_scores.iter()); + println!("Scores tuple: {:?} (Intermediate not necessary, just to see what is happening)", scores_tuple); + + let scores: HashMap<_, _> = scores_tuple.collect(); + println!("Scores: {:?}", scores); + + let team_name = String::from("Blue"); + match scores.get(&team_name) { + Some(sc) => println!("{} team score is: {}", &team_name, sc), + None => println!("No score for team: {}", &team_name), + } + + for (key, value) in &scores { + println!("{}: {}", key, value); + } + + let mut scores = HashMap::new(); + + scores.insert(String::from("Blue"), 10); + scores.insert(String::from("Yellow"), 50); + + scores.insert(String::from("Blue"), 25); // Overwriting a value + + for (key, value) in &scores { + println!("{}: {}", key, value); + } + + scores.entry(String::from("Blue")).or_insert(50); // Only insert if the value does not exist + scores.entry(String::from("Red")).or_insert(50); + println!("{:?}", scores); + + let text = "hello world wonderful world"; + let mut map = HashMap::new(); + + for word in text.split_whitespace() { + let count = map.entry(word).or_insert(0); + *count += 1; + } + println!("{:?}", map); + + println!("The hashing function is cryptographically secure. If it's slow, use an other one implementing the `BuildHasher` trait."); + + println!(); +}