Assign a String to a second variable, then try using the first name. Rust rejects that use because ownership has moved.[1] Following the owner explains which name remains available and where the text will be cleaned up.[1]
Follow one value
Each Rust value has an owner. There is one owner at a time; when the owner goes out of scope, the value is dropped.[1] A scope is the region where a variable is valid, often bounded by braces.[1]
Tested on Linux ARM64 with rustc 1.99.1 and Cargo 1.99.1. Create a fresh project, then open its ownership folder in your editor and terminal.
cargo new --vcs none ownership
$ cargo new --vcs none ownership Creating binary (application) `ownership` packagenote: see more `Cargo.toml` keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.htmlexit=0
Replace src/main.rs with this complete programme.
fn main() { let original = String::from("notes"); let current = original; println!("{current}");}
String::from("notes") creates an owned String from the quoted text. String owns its contents in a heap-allocated buffer, an area of memory holding the text.[2] Here, original is its first owner.
The next statement moves that String into current. The existing text buffer stays allocated, and original becomes unavailable for reading.[1] At the closing brace of main, current goes out of scope and its String releases the buffer.[1]
Run from the ownership folder. Captures include the executed command and exit status.
cargo run --quiet
$ cargo run --quietnotesexit=0

A common error: using the old owner
Replace src/main.rs with this deliberately failing version. The extra final line attempts to read original after the move.
fn main() { let original = String::from("notes"); let current = original; println!("{current}"); println!("{original}");}
Check this version. Failure is expected.
cargo check --quiet
$ cargo check --quieterror[E0382]: borrow of moved value: `original` --> src/main.rs:5:16 |2 | let original = String::from("notes"); | -------- move occurs because `original` has type `String`, which does not implement the `Copy` trait3 | let current = original; | -------- value moved here4 | println!("{current}");5 | println!("{original}"); | ^^^^^^^^ value borrowed here after move |help: consider cloning the value if the performance cost is acceptable |3 | let current = original.clone(); | ++++++++For more information about this error, try `rustc --explain E0382`.error: could not compile `ownership` (bin "ownership") due to 1 previous errorexit=101
Our check returned E0382 and exit 101. Its arrows identify the declaration, the move and the later attempted use.
E0382 reports use of a value after it has moved.[3]
Remove the final line to restore the working programme. Read the move location before changing types or adding mut.
This behaviour depends on the type. Integers implement Copy, so assigning an integer allows both variables to remain usable. String moves in this assignment.[1]
Exercise
Restore the working version. Rename current to saved and change notes to shopping. Run it and expect shopping.
Next: references let a function borrow a value while its caller keeps ownership.
Browse Rust, one step at a time
Leave a Reply