almost done

This commit is contained in:
Esteban Escobar 2023-02-18 08:37:13 -05:00
parent b4fed47104
commit e5225cb7c8
13 changed files with 59 additions and 45 deletions

View File

@ -30,6 +30,11 @@ return results to new Vec<i32> vector
31) box.rs for smart pointer to allocate memory in recursive types 31) box.rs for smart pointer to allocate memory in recursive types
32) arc.rs for atomic reference counters, moving ownershup to thread::spawn. 32) arc.rs for atomic reference counters, moving ownershup to thread::spawn.
33) rc.rs Rc::strong_count, Rc::new and Rc::clone, and drop(). Also note "In summary, if you need shared ownership in a single-threaded context, you can use Rc. If you need shared ownership across multiple threads, you should use Arc." Rc is faster and smaller than Arc 33) rc.rs Rc::strong_count, Rc::new and Rc::clone, and drop(). Also note "In summary, if you need shared ownership in a single-threaded context, you can use Rc. If you need shared ownership across multiple threads, you should use Arc." Rc is faster and smaller than Arc
34) Cow
35) All threads exercises :(. handles and join methods for thread completion wait in the main thread.
36) threads2 exercises important for understanding synchorization primitize Mutex
37) threads3 - again - all threads exercises.
38) all macros exercises
clippy conversions macros threads conversions

View File

@ -6,12 +6,10 @@
// check clippy's suggestions from the output to solve the exercise. // check clippy's suggestions from the output to solve the exercise.
// Execute `rustlings hint clippy1` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint clippy1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
use std::f32; use std::f32;
fn main() { fn main() {
let pi = 3.14f32; let pi = f32::consts::PI;
let radius = 5.00f32; let radius = 5.00f32;
let area = pi * f32::powi(radius, 2); let area = pi * f32::powi(radius, 2);

View File

@ -1,12 +1,10 @@
// clippy2.rs // clippy2.rs
// Execute `rustlings hint clippy2` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint clippy2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
fn main() { fn main() {
let mut res = 42; let mut res = 42;
let option = Some(12); let option = Some(12);
for x in option { if let Some(x) = option {
res += x; res += x;
} }
println!("{}", res); println!("{}", res);

View File

@ -1,28 +1,27 @@
// clippy3.rs // clippy3.rs
// Here's a couple more easy Clippy fixes, so you can see its utility. // Here's a couple more easy Clippy fixes, so you can see its utility.
// I AM NOT DONE
#[allow(unused_variables, unused_assignments)] #[allow(unused_variables, unused_assignments)]
fn main() { fn main() {
let my_option: Option<()> = None; let my_option: Option<()> = None;
if my_option.is_none() { if let Some(x) = my_option {
my_option.unwrap(); my_option.unwrap();
} }
let my_arr = &[ let my_arr = &[
-1, -2, -3 -1, -2, -3,
-4, -5, -6 -4, -5, -6
]; ];
println!("My array! Here it is: {:?}", my_arr); println!("My array! Here it is: {:?}", my_arr);
let my_empty_vec = vec![1, 2, 3, 4, 5].resize(0, 5); let my_empty_vec = vec![1, 2, 3, 4, 5].clear();
println!("This Vec is empty, see? {:?}", my_empty_vec); println!("This Vec is empty, see? {:?}", my_empty_vec);
let mut value_a = 45; let mut value_a = 45;
let mut value_b = 66; let mut value_b = 66;
// Let's swap these two! // Let's swap these two!
value_a = value_b; std::mem::swap(&mut value_a, &mut value_b);
value_b = value_a; // value_a = value_b;
// value_b = value_a;
println!("value a: {}; value b: {}", value_a, value_b); println!("value a: {}; value b: {}", value_a, value_b);
} }

View File

@ -35,10 +35,27 @@ impl Default for Person {
// If while parsing the age, something goes wrong, then return the default of Person // If while parsing the age, something goes wrong, then return the default of Person
// Otherwise, then return an instantiated Person object with the results // Otherwise, then return an instantiated Person object with the results
// I AM NOT DONE
impl From<&str> for Person { impl From<&str> for Person {
fn from(s: &str) -> Person { fn from(s: &str) -> Person {
if s.to_string().len() == 0 {
Person::default()
} else {
let person_attr: Vec<&str> = s.split(",").collect();
match person_attr.len() {
2 => match person_attr[0] {
"" => Person::default(),
_ => match person_attr[1] {
"" => Person::default(),
_ => match person_attr[1].parse::<usize>() {
Ok(person_age) => Person{name: person_attr[0].to_string(), age: person_age},
Err(_) => Person::default()
}
}
},
_ => Person::default()
}
}
} }
} }

View File

@ -6,11 +6,9 @@
// and returns the proper type. // and returns the proper type.
// Execute `rustlings hint using_as` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint using_as` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
fn average(values: &[f64]) -> f64 { fn average(values: &[f64]) -> f64 {
let total = values.iter().sum::<f64>(); let total = values.iter().sum::<f64>();
total / values.len() total / values.len() as f64
} }
fn main() { fn main() {

View File

@ -1,8 +1,7 @@
// macros1.rs // macros1.rs
// Execute `rustlings hint macros1` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint macros1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE #[macro_export]
macro_rules! my_macro { macro_rules! my_macro {
() => { () => {
println!("Check out my macro!"); println!("Check out my macro!");
@ -10,5 +9,5 @@ macro_rules! my_macro {
} }
fn main() { fn main() {
my_macro(); my_macro!();
} }

View File

@ -1,12 +1,11 @@
// macros2.rs // macros2.rs
// Execute `rustlings hint macros2` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint macros2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
fn main() { fn main() {
my_macro!(); my_macro!();
} }
#[macro_export]
macro_rules! my_macro { macro_rules! my_macro {
() => { () => {
println!("Check out my macro!"); println!("Check out my macro!");

View File

@ -2,8 +2,7 @@
// Make me compile, without taking the macro out of the module! // Make me compile, without taking the macro out of the module!
// Execute `rustlings hint macros3` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint macros3` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE #[macro_use]
mod macros { mod macros {
macro_rules! my_macro { macro_rules! my_macro {
() => { () => {

View File

@ -1,12 +1,10 @@
// macros4.rs // macros4.rs
// Execute `rustlings hint macros4` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint macros4` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
macro_rules! my_macro { macro_rules! my_macro {
() => { () => {
println!("Check out my macro!"); println!("Check out my macro!");
} };
($val:expr) => { ($val:expr) => {
println!("Look at this other macro: {}", $val); println!("Look at this other macro: {}", $val);
} }

View File

@ -2,8 +2,6 @@
// Execute `rustlings hint threads1` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint threads1` or use the `hint` watch subcommand for a hint.
// This program should wait until all the spawned threads have finished before exiting. // This program should wait until all the spawned threads have finished before exiting.
// I AM NOT DONE
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
@ -12,15 +10,16 @@ fn main() {
let mut handles = vec![]; let mut handles = vec![];
for i in 0..10 { for i in 0..10 {
thread::spawn(move || { handles.push(thread::spawn(move || {
thread::sleep(Duration::from_millis(250)); thread::sleep(Duration::from_millis(250));
println!("thread {} is complete", i); println!("thread {} is complete", i);
}); }));
} }
let mut completed_threads = 0; let mut completed_threads = 0;
for handle in handles { for handle in handles {
// TODO: a struct is returned from thread::spawn, can you use it? // TODO: a struct is returned from thread::spawn, can you use it?
handle.join().unwrap();
completed_threads += 1; completed_threads += 1;
} }

View File

@ -3,25 +3,25 @@
// Building on the last exercise, we want all of the threads to complete their work but this time // Building on the last exercise, we want all of the threads to complete their work but this time
// the spawned threads need to be in charge of updating a shared value: JobStatus.jobs_completed // the spawned threads need to be in charge of updating a shared value: JobStatus.jobs_completed
// I AM NOT DONE
use std::sync::Arc; use std::sync::Arc;
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
use std::sync::Mutex;
struct JobStatus { struct JobStatus {
jobs_completed: u32, jobs_completed: u32,
} }
fn main() { fn main() {
let status = Arc::new(JobStatus { jobs_completed: 0 }); let status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 }));
let mut handles = vec![]; let mut handles = vec![];
for _ in 0..10 { for _ in 0..10 {
let status_shared = Arc::clone(&status); let status_shared = Arc::clone(&status);
let handle = thread::spawn(move || { let handle = thread::spawn(move || {
thread::sleep(Duration::from_millis(250)); thread::sleep(Duration::from_millis(250));
// TODO: You must take an action before you update a shared value // TODO: You must take an action before you update a shared value
status_shared.jobs_completed += 1; let mut status = (*status_shared).lock().unwrap(); //do a deref so you can do lock on Mutex sync primitive
status.jobs_completed += 1;
}); });
handles.push(handle); handles.push(handle);
} }
@ -29,6 +29,6 @@ fn main() {
handle.join().unwrap(); handle.join().unwrap();
// TODO: Print the value of the JobStatus.jobs_completed. Did you notice anything // TODO: Print the value of the JobStatus.jobs_completed. Did you notice anything
// interesting in the output? Do you have to 'join' on all the handles? // interesting in the output? Do you have to 'join' on all the handles?
println!("jobs completed {}", ???); println!("jobs completed {}", status.lock().unwrap().jobs_completed);
} }
} }

View File

@ -1,10 +1,8 @@
// threads3.rs // threads3.rs
// Execute `rustlings hint threads3` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint threads3` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
use std::sync::mpsc; use std::sync::mpsc;
use std::sync::Arc; use std::sync::{Arc, Mutex};
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
@ -24,23 +22,29 @@ impl Queue {
} }
} }
fn send_tx(q: Queue, tx: mpsc::Sender<u32>) -> () { fn send_tx(q: Queue, mytx: Arc<Mutex<mpsc::Sender<u32>>>) -> () {
let qc = Arc::new(q); let qc = Arc::new(q);
let qc1 = Arc::clone(&qc); let qc1 = Arc::clone(&qc);
let qc2 = Arc::clone(&qc); let qc2 = Arc::clone(&qc);
let tx1 = Arc::clone(&mytx);
thread::spawn(move || { thread::spawn(move || {
for val in &qc1.first_half { for val in &qc1.first_half {
println!("sending {:?}", val); println!("sending {:?}", val);
tx.send(*val).unwrap(); let mytx = tx1.lock().unwrap();
mytx.send(*val).unwrap();
thread::sleep(Duration::from_secs(1)); thread::sleep(Duration::from_secs(1));
} }
}); });
let tx2 = Arc::clone(&mytx);
thread::spawn(move || { thread::spawn(move || {
for val in &qc2.second_half { for val in &qc2.second_half {
println!("sending {:?}", val); println!("sending {:?}", val);
tx.send(*val).unwrap(); let mytx = tx2.lock().unwrap();
mytx.send(*val).unwrap();
thread::sleep(Duration::from_secs(1)); thread::sleep(Duration::from_secs(1));
} }
}); });
@ -51,7 +55,8 @@ fn main() {
let queue = Queue::new(); let queue = Queue::new();
let queue_length = queue.length; let queue_length = queue.length;
send_tx(queue, tx); let newtx = Arc::new(Mutex::new(tx));
send_tx(queue, newtx);
let mut total_received: u32 = 0; let mut total_received: u32 = 0;
for received in rx { for received in rx {