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.