> For the complete documentation index, see [llms.txt](https://bagus-cahyono.gitbook.io/programming-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bagus-cahyono.gitbook.io/programming-notes/rust/rustlings_exercise/06_move_semantics.md).

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


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bagus-cahyono.gitbook.io/programming-notes/rust/rustlings_exercise/06_move_semantics.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
