Why does function not take the ownership of Option argument?

ghz 8months ago ⋅ 87 views

I test the code below:

fn main() {
    let tested = Some(5);
    testoption(tested);
    println!("the tested is {}", tested.unwrap());
}

fn testoption(p: Option<i32>) {
    println!("the argument is {}", p.unwrap());
}

The variable tested can be used after the function is called. I thought it should be moved.

So, what kind of variable would not be moved after the function call? Implement the Copy trait Or something else?

Answers

In Rust, ownership rules dictate that values are moved by default when passed into functions. However, types that implement the Copy trait are exceptions to this rule. When a value of a Copy type is passed into a function, it is copied rather than moved, allowing the original value to remain accessible after the function call.

The Copy trait represents types whose values can be copied bitwise without modifying the original value. Basic scalar types like integers, floating-point numbers, booleans, characters, and references (including slices) implement the Copy trait. Here's an example:

fn main() {
    let tested = 5; // `tested` is of a type that implements `Copy`
    test_copy(tested);
    println!("the tested is {}", tested); // `tested` is still accessible
}

fn test_copy(p: i32) {
    println!("the argument is {}", p);
}

In this example, tested is of type i32, which implements the Copy trait. Therefore, when tested is passed into the test_copy function, it is copied rather than moved, allowing the original value to remain accessible in the main function.

It's important to note that only types that do not require resources beyond memory (e.g., scalars) can implement Copy. Complex types like strings, vectors, and custom types that contain references or implement the Drop trait cannot implement Copy. For these types, ownership transfer (move semantics) is enforced to avoid issues related to resource management.