Skip to content

Instantly share code, notes, and snippets.

@totechite
Last active May 17, 2023 02:33
Show Gist options
  • Save totechite/6dce08cf75ab961e546f0578cdfbb27c to your computer and use it in GitHub Desktop.
Save totechite/6dce08cf75ab961e546f0578cdfbb27c to your computer and use it in GitHub Desktop.

Revisions

  1. totechite revised this gist Oct 3, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion move_semantics3.rs
    Original file line number Diff line number Diff line change
    @@ -6,7 +6,7 @@
    pub fn main() {
    let vec0 = Vec::new();

    let mut vec1 = fill_vec(vec0.clone());
    let mut vec1 = fill_vec(vec0);

    println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);

  2. totechite revised this gist Oct 3, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion move_semantics1.rs
    Original file line number Diff line number Diff line change
    @@ -6,7 +6,7 @@ pub fn main() {

    let mut vec1 = fill_vec(vec0);

    println!("{} has length {} content `{:?}`", "vec1", vec1.len(), &vec1);
    println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);

    vec1.push(88);

  3. totechite revised this gist Oct 3, 2018. 2 changed files with 89 additions and 0 deletions.
    46 changes: 46 additions & 0 deletions move_semantics3.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,46 @@
    // move_semantics3.rs
    // 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.clone());

    println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);

    vec1.push(88);

    println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);

    }

    fn fill_vec(mut 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 :)
    43 changes: 43 additions & 0 deletions move_semantics4.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,43 @@
    // move_semantics4.rs
    // 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 mut vec1 = fill_vec();

    println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);

    vec1.push(88);

    println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);

    }

    fn fill_vec() -> Vec<i32> {
    [22, 44, 66].to_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`
  4. totechite created this gist Oct 3, 2018.
    43 changes: 43 additions & 0 deletions move_semantics1.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,43 @@
    // move_semantics1.rs
    // Make me compile! 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> {
    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 11,
    // right? The fix for this is going to be adding one keyword, and the addition is NOT on line 11
    // where the error is.
    54 changes: 54 additions & 0 deletions move_semantics2-1.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,54 @@
    // move_semantics2.rs
    // Make me compile without changing line 10! Scroll down for hints :)

    pub fn main() {
    let vec0 = Vec::new();

    let mut vec1 = fill_vec(vec0.clone());

    // 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 7, which means it gets dropped at the end of `fill_vec`, which means we
    // can't use `vec0` again on line 10 (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!`
    54 changes: 54 additions & 0 deletions move_semantics2-2.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,54 @@
    // move_semantics2.rs
    // Make me compile without changing line 10! 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.clone();

    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 7, which means it gets dropped at the end of `fill_vec`, which means we
    // can't use `vec0` again on line 10 (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!`
    49 changes: 49 additions & 0 deletions move_semantics2-3.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,49 @@
    // move_semantics2.rs
    // Make me compile without changing line 10! Scroll down for hints :)

    pub fn main() {
    let mut vec0 = Vec::new();

    fill_vec(&mut vec0);

    // Do not change the following line!
    println!("{} has length {} content `{:?}`", "vec0", vec0.len(), vec0);

    }

    fn fill_vec(vec: &mut Vec<i32>) {
    let vec = vec;

    vec.push(22);
    vec.push(44);
    vec.push(66);

    }














    // So `vec0` is being *moved* into the function `fill_vec` when we call it on
    // line 7, which means it gets dropped at the end of `fill_vec`, which means we
    // can't use `vec0` again on line 10 (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!`