Main exercises
This commit is contained in:
parent
278a1f103b
commit
34aafa82f9
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
// This exercise uses some concepts that we won't get to until later in the course, like `Box` and the
|
// This exercise uses some concepts that we won't get to until later in the course, like `Box` and the
|
||||||
// `From` trait. It's not important to understand them in detail right now, but you can read ahead if you like.
|
// `From` trait. It's not important to understand them in detail right now, but you can read ahead if you like.
|
||||||
// For now, think of the `Box<dyn ...>` type as an "I want anything that does ???" type, which, given
|
// For now, think of the `Box<dyn ???>` type as an "I want anything that does ???" type, which, given
|
||||||
// Rust's usual standards for runtime safety, should strike you as somewhat lenient!
|
// Rust's usual standards for runtime safety, should strike you as somewhat lenient!
|
||||||
|
|
||||||
// In short, this particular use case for boxes is for when you want to own a value and you care only that it is a
|
// In short, this particular use case for boxes is for when you want to own a value and you care only that it is a
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
macro_rules! my_macro {
|
macro_rules! my_macro {
|
||||||
() => {
|
() => {
|
||||||
println!("Check out my macro!");
|
println!("Check out my macro!");
|
||||||
|
|
|
@ -32,7 +32,7 @@ fn main() {
|
||||||
for offset in 0..8 {
|
for offset in 0..8 {
|
||||||
let child_numbers = // TODO
|
let child_numbers = // TODO
|
||||||
joinhandles.push(thread::spawn(move || {
|
joinhandles.push(thread::spawn(move || {
|
||||||
let sum: u32 = child_numbers.iter().filter(|n| *n % 8 == offset).sum();
|
let sum: u32 = child_numbers.iter().filter(|&&n| n % 8 == offset).sum();
|
||||||
println!("Sum of offset {} is {}", offset, sum);
|
println!("Sum of offset {} is {}", offset, sum);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
// Cow is a clone-on-write smart pointer.
|
// Cow is a clone-on-write smart pointer.
|
||||||
// It can enclose and provide immutable access to borrowed data, and clone the data lazily when mutation or ownership is required.
|
// It can enclose and provide immutable access to borrowed data, and clone the data lazily when mutation or ownership is required.
|
||||||
// The type is designed to work with general borrowed data via the Borrow trait.
|
// The type is designed to work with general borrowed data via the Borrow trait.
|
||||||
|
//
|
||||||
|
// This exercise is meant to show you what to expect when passing data to Cow.
|
||||||
|
// Fix the unit tests by checking for Cow::Owned(_) and Cow::Borrowed(_) at the TODO markers.
|
||||||
|
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
|
||||||
|
@ -20,29 +23,52 @@ fn abs_all<'a, 'b>(input: &'a mut Cow<'b, [i32]>) -> &'a mut Cow<'b, [i32]> {
|
||||||
input
|
input
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
#[cfg(test)]
|
||||||
// No clone occurs because `input` doesn't need to be mutated.
|
mod tests {
|
||||||
let slice = [0, 1, 2];
|
use super::*;
|
||||||
let mut input = Cow::from(&slice[..]);
|
|
||||||
match abs_all(&mut input) {
|
|
||||||
Cow::Borrowed(_) => println!("I borrowed the slice!"),
|
|
||||||
_ => panic!("expected borrowed value"),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reference_mutation() -> Result<(), &'static str> {
|
||||||
// Clone occurs because `input` needs to be mutated.
|
// Clone occurs because `input` needs to be mutated.
|
||||||
let slice = [-1, 0, 1];
|
let slice = [-1, 0, 1];
|
||||||
let mut input = Cow::from(&slice[..]);
|
let mut input = Cow::from(&slice[..]);
|
||||||
match abs_all(&mut input) {
|
match abs_all(&mut input) {
|
||||||
Cow::Owned(_) => println!("I modified the slice and now own it!"),
|
Cow::Owned(_) => Ok(()),
|
||||||
_ => panic!("expected owned value"),
|
_ => Err("Expected owned value"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No clone occurs because `input` is already owned.
|
#[test]
|
||||||
|
fn reference_no_mutation() -> Result<(), &'static str> {
|
||||||
|
// No clone occurs because `input` doesn't need to be mutated.
|
||||||
|
let slice = [0, 1, 2];
|
||||||
|
let mut input = Cow::from(&slice[..]);
|
||||||
|
match abs_all(&mut input) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn owned_no_mutation() -> Result<(), &'static str> {
|
||||||
|
// We can also pass `slice` without `&` so Cow owns it directly.
|
||||||
|
// In this case no mutation occurs and thus also no clone,
|
||||||
|
// but the result is still owned because it always was.
|
||||||
|
let slice = vec![0, 1, 2];
|
||||||
|
let mut input = Cow::from(slice);
|
||||||
|
match abs_all(&mut input) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn owned_mutation() -> Result<(), &'static str> {
|
||||||
|
// Of course this is also the case if a mutation does occur.
|
||||||
|
// In this case the call to `to_mut()` returns a reference to
|
||||||
|
// the same data as before.
|
||||||
let slice = vec![-1, 0, 1];
|
let slice = vec![-1, 0, 1];
|
||||||
let mut input = Cow::from(slice);
|
let mut input = Cow::from(slice);
|
||||||
match abs_all(&mut input) {
|
match abs_all(&mut input) {
|
||||||
// TODO
|
// TODO
|
||||||
Cow::Borrowed(_) => println!("I own this slice!"),
|
}
|
||||||
_ => panic!("expected borrowed value"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,3 +13,5 @@ the other useful data structure, hash maps, later.
|
||||||
## Further information
|
## Further information
|
||||||
|
|
||||||
- [Storing Lists of Values with Vectors](https://doc.rust-lang.org/stable/book/ch08-01-vectors.html)
|
- [Storing Lists of Values with Vectors](https://doc.rust-lang.org/stable/book/ch08-01-vectors.html)
|
||||||
|
- [`iter_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.iter_mut)
|
||||||
|
- [`map`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.map)
|
||||||
|
|
Loading…
Reference in New Issue