X-Git-Url: https://piware.de/gitweb/?p=learn-rust.git;a=blobdiff_plain;f=concepts%2Fsrc%2Fmain.rs;fp=concepts%2Fsrc%2Fmain.rs;h=06d122b9c4c727f399d8273312ffcfb2a95088fd;hp=0000000000000000000000000000000000000000;hb=b653e9fe9d8492f2d4b5419721f7e00b392055f9;hpb=8c240f514e17c9a935f5f392e6a87779ae1c09e8 diff --git a/concepts/src/main.rs b/concepts/src/main.rs new file mode 100644 index 0000000..06d122b --- /dev/null +++ b/concepts/src/main.rs @@ -0,0 +1,200 @@ +mod word_utils; +mod lib; + +use std::collections::HashMap; +use std::io::{prelude::*, ErrorKind}; +use std::fs::{self, File}; + +use lib::*; +use word_utils::{first_word, second_word}; + +fn test_strings() { + let s = String::from("Hello world"); + println!("first word: '{}'", first_word(&s)); + println!("second word: '{}'", second_word(&s).unwrap()); + + let s2 = "hello dude blah"; + println!("second word of single: '{}'", second_word(s2).unwrap_or("(none)")); + + match second_word(s2) { + Some(w) => println!("match: second word of '{}' exists: {}", s2, w), + None => println!("match: second word of '{}' does not exist", s2), + } +} + +fn test_vectors() { + let v1 = vec![1, 2, 3]; + println!("statically initialized vector: {:?}", v1); + + let mut v2: Vec = Vec::new(); + v2.push("Hello".to_string()); + v2.push(String::from("world")); + println!("dynamically built vector: {:?}", v2); + println!("first element: {}", v2[0]); + for el in &mut v2 { + *el += "xx"; + } + for el in &v2 { + println!("{}", el); + } +} + +fn test_hashmaps() { + let mut scores = HashMap::new(); + scores.insert("john", 10); + scores.insert("mary", 20); + + println!("scores: {:?}", scores); + + // hash map with .collect() + let persons = vec![("homer", 42), ("marge", 30)]; + let collect_scores: HashMap<_, _> = persons.into_iter().collect(); + println!("collect_scores: {:?}", collect_scores); + + for (p, s) in &collect_scores { + println!("person {}: score {}", p, s); + } + + println!("john's score: {}", scores.get("john").unwrap()); + println!("jake's score: {}", scores.get("jake").unwrap_or(&-1)); + + // double scores + for (_, v) in scores.iter_mut() { + *v *= 2; + } + println!("scores after doubling: {:?}", scores); + + // double scores of immutable hashmap (rebuild it) + let collect_scores: HashMap<_, _> = collect_scores.into_iter() + .map(|(k, v)| (k, 2 * v)) + .collect(); + println!("collect_scores after rebuilding with doubling: {:?}", collect_scores); +} + +fn test_files() { + if let Ok(mut f) = File::open("Cargo.toml") { + let mut contents = String::new(); + match f.read_to_string(&mut contents) { + Ok(len) => println!("successfully opened Cargo.toml: {:?}, contents {} bytes:\n{}\n----------", f, len, contents), + Err(e) => panic!("could not read file: {:?}", e) + } + } else { + println!("could not open Cargo.toml"); + } + + // alternative form, more specific error checking + let mut f = File::open("Cargo.toml").unwrap_or_else(|e| { + if e.kind() == ErrorKind::NotFound { + println!("Cargo.toml not found, falling back to /dev/null"); + // need to return a File + File::open("/dev/null").unwrap() + } else { + panic!("Could not open Cargo.toml: {:?}", e); + } + }); + let mut contents = String::new(); + let len = f.read_to_string(&mut contents).unwrap_or_else(|e| { + panic!("Could not read file: {:?}", e); + }); + println!("successfully opened Cargo.toml with unwrap_or_else: {:?}, contents {} bytes:\n{}\n----------", f, len, contents); + + // using the '?' operator + match read_file("Cargo.toml") { + Ok(s) => println!("Cargo.toml contents:\n{}\n-------------", s), + Err(e) => println!("Could not open Cargo.toml: {:?}", e) + } + + // using std API + match fs::read_to_string("Cargo.toml") { + Ok(s) => println!("Cargo.toml contents:\n{}\n-------------", s), + Err(e) => println!("Could not open Cargo.toml: {:?}", e) + } +} + +fn test_generics() { + let num_list = vec![3, 42, -7, 100, 0]; + println!("largest number: {}", largest(&num_list)); + println!("num_list: {:?}", num_list); + + let char_list = vec!['a', 'y', 'q', 'm']; + println!("largest char: {}", largest(&char_list)); + + let str_list = vec!["hello", "world", "blue", "planet"]; + println!("largest str: {}", largest(&str_list)); + println!("str_list: {:?}", str_list); + + let string_list = vec!["aaaa".to_string(), "xxxxx".to_string(), "ffff".to_string()]; + println!("largest string (with cloning): {}", largest_clone(&string_list)); + println!("largest string (with ref): {}", largest_ref(&string_list)); + println!("string_list: {:?}", string_list); + + let s1 = String::from("abcd"); + let l; + { + let s2 = "efghi"; + l = longest(&s1, s2); + } + println!("longest string: {}", l); +} + +fn test_closures() { + let mut expensive_int_result = Cacher::new(|x| { + println!("calculating expensive int result for {}", x); + 2 * x + }); + + println!("1st int call for value 1: {}", expensive_int_result.value(1)); + println!("2nd int call for value 1: {}", expensive_int_result.value(1)); + println!("1st int call for value 2: {}", expensive_int_result.value(2)); + + let mut expensive_str_result = Cacher::new(|x: &str| { + println!("calculating expensive str result for {}", x); + x.len() + }); + + println!("1st int call for value abc: {}", expensive_str_result.value("abc")); + println!("2nd int call for value abc: {}", expensive_str_result.value("abc")); + println!("1st int call for value defg: {}", expensive_str_result.value("defg")); +} + +fn test_iterators() { + let v1 = vec!["Hello", "good", "world"]; + // implied default is .into_iter() which consumes v1 + for s in v1.iter() { + println!("element: {}", s); + } + // can still use it now + println!("v1: {:?}", &v1); + + // manual iteration + let mut v1_iter = v1.iter(); + while let Some(e) = v1_iter.next() { + println!("while loop over iter: {}", e); + } + + for l_element in v1.iter().filter(|x| x.contains('l')) { + println!("v1 element containing 'l': {}", l_element); + } + + let v2 = vec![1, 2, 3]; + let double_v2: Vec<_> = v2.iter().map(|x| x * 2).collect(); + println!("doubled v2: {:?}", double_v2); + + for i in v2.into_iter().map(|x| x * 3) { + println!("for loop triplicating v2: {}", i); + } + + for i in Counter5::new() { + println!("Counter 5 value: {}", i); + } +} + +fn main() { + test_strings(); + test_vectors(); + test_hashmaps(); + test_files(); + test_generics(); + test_closures(); + test_iterators(); +}