# 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.
* References:
  * [Ownership](https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html)
  * [Reference and borrowing](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html)

## move\_semantics1.rs

```rust
// 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

```rust
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::*;

    // TODO: Make both vectors `vec0` and `vec1` accessible at the same time to
    // fix the compiler error in the test.
    #[test]
    fn move_semantics2() {
        let vec0 = vec![22, 44, 66];

        let vec1 = fill_vec(vec0.clone()); // pass cloned vec0

        assert_eq!(vec0, [22, 44, 66]);
        assert_eq!(vec1, [22, 44, 66, 88]);
    }
}
```

* 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:

  ```rust
  borrow of moved value: `vec0`
  ```
* So instead of passing `vec0` we pass a ***clone*** of `vec0`.
* That makes both `vec0` and `vec1` valid.

## move\_semantics3.rs

```rust
// TODO: Fix the compiler error in the function without adding any new line.
fn fill_vec(mut vec: Vec<i32>) -> Vec<i32> { 
    //      ^^^ add mut
    vec.push(88);

    vec
}

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

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

    #[test]
    fn move_semantics3() {
        let vec0 = vec![22, 44, 66];
        let vec1 = fill_vec(vec0);
        assert_eq!(vec1, [22, 44, 66, 88]);
    }
}
```

* 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

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

#[cfg(test)]
mod tests {
    // TODO: Fix the compiler errors only by reordering the lines in the test.
    // Don't add, change or remove any line.
    #[test]
    fn move_semantics4() {
        let mut x = Vec::new();
        let y = &mut x;
        y.push(42); // move this line above z
        let z = &mut x;
        z.push(13);
        assert_eq!(x, [42, 13]);
    }
}
```

* 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.

  ```rust
  error[E0499]: cannot borrow `x` as mutable more than once at a time
    --> exercises/06_move_semantics/move_semantics4.rs:13:17
     |
  12 |         let y = &mut x;
     |                 ------ first mutable borrow occurs here
  13 |         let z = &mut x;
     |                 ^^^^^^ second mutable borrow occurs here
  14 |         y.push(42);
     |         - first borrow later used here
  ```
* 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

```rust
#![allow(clippy::ptr_arg)]

// TODO: Fix the compiler errors without changing anything except adding or
// removing references (the character `&`).

// Shouldn't take ownership
// add & to borrow instead
fn get_char(data: &String) -> char {
    data.chars().last().unwrap()
}

// Should take ownership
fn string_uppercase(mut data: String) {
    data = data.to_uppercase();

    println!("{data}");
}

fn main() {
    let data = "Rust is great!".to_string();

    get_char(&data);

    string_uppercase(data);
}
```

* 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.
