Move Semantics

  • Each value in Rust has an owner.

  • There can only be one owner at a time.

  • When the owner goes out of scope, the value will be dropped.

  • When assigning a value to another variable or passing it to a function, ownership is transferred (moved).

  • Borrowing lets you access a value without transferring ownership, using references (&).

  • You can have only one mutable reference or any number of immutable references at a time.

move_semantics1.rs

// TODO: Fix the compiler error in this function.
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
    let mut vec = vec;

    vec.push(88);

    vec
}

fn main() {
    // You can optionally experiment here.
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn move_semantics1() {
        let vec0 = vec![22, 44, 66];
        let vec1 = fill_vec(vec0);
        assert_eq!(vec1, vec![22, 44, 66, 88]);
    }
}
  • In this exercise the function fill_vec tried to change vec variables.

  • But it got compile error because vec is not mutable.

  • When passing vec0 into function fill_vec it also transfer or move the ownership from main function to fill_vec function.

  • So fill_vec as the owner can do anything with it including change the mutability.

  • Then we can easily add mutable in here let mut vec = vec; to fix the code.

  • And that makes vec is mutable and we can push value into it.

move_semantics2.rs

  • In this exercise the task is to make both vec0 and vec1 accessible at the same time.

  • If we pass vec0 to function fill_vec it will transfer or move the ownership.

  • That make the vec0 variable invalidated and we got error:

  • So instead of passing vec0 we pass a clone of vec0.

  • That makes both vec0 and vec1 valid.

move_semantics3.rs

  • This exercise is similar with move_semantics1.rs.

  • But instead of changing the mutability by redeclare variables with mut we do it inside the function parameters.

move_semantics4.rs

  • You can have only one mutable reference or any number of immutable references at a time.

  • So the original code have compile error because of x have more than one mutable reference.

  • By simply moving y.push(42); above let z = &mut x; we can fix it.

  • Because y already done with the push so x is free and can be borrowed by z in the next step.

move_semantics5.rs

  • If we look at the comment the function string_uppercase it shouldn't take ownership but the original code does it.

  • So we just need to add reference data: &String to the parameter and pass &data when calling get_char.

  • That makes it borrow instead of move.

  • For string_uppercase remove the reference from data parameters because we want to move the ownership to it and remove the reference too when calling it.

Last updated