diff options
Diffstat (limited to 'move_semantics')
| -rw-r--r-- | move_semantics/move_semantics1.rs | 42 | ||||
| -rw-r--r-- | move_semantics/move_semantics2.rs | 53 | ||||
| -rw-r--r-- | move_semantics/move_semantics3.rs | 45 | ||||
| -rw-r--r-- | move_semantics/move_semantics4.rs | 47 |
4 files changed, 187 insertions, 0 deletions
diff --git a/move_semantics/move_semantics1.rs b/move_semantics/move_semantics1.rs new file mode 100644 index 0000000..f109765 --- /dev/null +++ b/move_semantics/move_semantics1.rs @@ -0,0 +1,42 @@ +// Make me compile! Scroll down for hints :) + +pub fn main() { + let vec0 = Vec::new(); + + let vec1 = fill_vec(vec0); + + println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1); + + vec1.push(88); + + println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1); + +} + +fn fill_vec(vec: Vec<i32>) -> Vec<i32> { + let mut vec = vec; + + vec.push(22); + vec.push(44); + vec.push(66); + + vec +} + + + + + + + + + + + + + + + +// So you've got the "cannot borrow immutable local variable `vec1` as mutable" error on line 8, +// right? The fix for this is going to be adding one keyword, and the addition is NOT on line 8 +// where the error is. diff --git a/move_semantics/move_semantics2.rs b/move_semantics/move_semantics2.rs new file mode 100644 index 0000000..79c1c56 --- /dev/null +++ b/move_semantics/move_semantics2.rs @@ -0,0 +1,53 @@ +// Make me compile without changing line 9! Scroll down for hints :) + +pub fn main() { + let vec0 = Vec::new(); + + let mut vec1 = fill_vec(vec0); + + // Do not change the following line! + println!("{} has length {} content `{:?}`", "vec0", vec0.len(), vec0); + + vec1.push(88); + + println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1); + +} + +fn fill_vec(vec: Vec<i32>) -> Vec<i32> { + let mut vec = vec; + + vec.push(22); + vec.push(44); + vec.push(66); + + vec +} + + + + + + + + + + + + + + +// So `vec0` is being *moved* into the function `fill_vec` when we call it on +// line 6, which means it gets dropped at the end of `fill_vec`, which means we +// can't use `vec0` again on line 9 (or anywhere else in `main` after the +// `fill_vec` call for that matter). We could fix this in a few ways, try them +// all! +// 1. Make another, separate version of the data that's in `vec0` and pass that +// to `fill_vec` instead. +// 2. Make `fill_vec` borrow its argument instead of taking ownership of it, +// and then copy the data within the function in order to return an owned +// `Vec<i32>` +// 3. Make `fill_vec` *mutably* borrow its argument (which will need to be +// mutable), modify it directly, then not return anything. Then you can get rid +// of `vec1` entirely -- note that this will change what gets printed by the +// first `println!` diff --git a/move_semantics/move_semantics3.rs b/move_semantics/move_semantics3.rs new file mode 100644 index 0000000..fec370f --- /dev/null +++ b/move_semantics/move_semantics3.rs @@ -0,0 +1,45 @@ +// Make me compile without adding new lines-- just changing existing lines! +// (no lines with multiple semicolons necessary!) +// Scroll down for hints :) + +pub fn main() { + let vec0 = Vec::new(); + + let mut vec1 = fill_vec(vec0); + + println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1); + + vec1.push(88); + + println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1); + +} + +fn fill_vec(vec: Vec<i32>) -> Vec<i32> { + vec.push(22); + vec.push(44); + vec.push(66); + + vec +} + + + + + + + + + + + + + + + + + +// The difference between this one and the previous ones is that the first line +// of `fn fill_vec` that had `let mut vec = vec;` is no longer there. You can, +// instead of adding that line back, add `mut` in one place that will change +// an existing binding to be a mutable binding instead of an immutable one :) diff --git a/move_semantics/move_semantics4.rs b/move_semantics/move_semantics4.rs new file mode 100644 index 0000000..17df426 --- /dev/null +++ b/move_semantics/move_semantics4.rs @@ -0,0 +1,47 @@ +// Refactor this code so that instead of having `vec0` and creating the vector +// in `fn main`, we instead create it within `fn fill_vec` and transfer the +// freshly created vector from fill_vec to its caller. Scroll for hints! + +pub fn main() { + let vec0 = Vec::new(); + + let mut vec1 = fill_vec(vec0); + + println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1); + + vec1.push(88); + + println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1); + +} + +fn fill_vec(vec: Vec<i32>) -> Vec<i32> { + let mut vec = vec; + + vec.push(22); + vec.push(44); + vec.push(66); + + vec +} + + + + + + + + + + + + +// Stop reading whenever you feel like you have enough direction :) Or try +// doing one step and then fixing the compiler errors that result! +// So the end goal is to: +// - get rid of the first line in main that creates the new vector +// - so then `vec0` doesn't exist, so we can't pass it to `fill_vec` +// - we don't want to pass anything to `fill_vec`, so its signature should +// reflect that it does not take any arguments +// - since we're not creating a new vec in `main` anymore, we need to create +// a new vec in `fill_vec`, similarly to the way we did in `main` |
