Move semantics transfer ownership instead of implicitly copying a value. The data need not physically move; Rust changes which binding may use it and checks that every use remains valid. section 4.1.1 section 4.4
Ownership can move through several ordinary language operations:
- Assignment transfers ownership from one binding to another, so the original binding can no longer be used. section 4.4
- Passing a value as a function argument moves ownership across the function boundary. section 4.4
- Returning a value can transfer ownership back to the calling scope. section 4.4
- Using move on a closure makes captured ownership belong to the closure, which may outlive its original scope. section 10.2.1
A CubeSat used after a move
A check_status(sat_a) call moves the CubeSat into the function. Calling check_status(sat_a) again fails with “use of moved value” because CubeSat does not implement Copy. Returning the CubeSat from check_status and rebinding it allows later calls. section 4.1.1 section 4.4
Listing 4.7 Returning ownership back to the original scope
#![allow(unused_variables)]
#[derive(Debug)]
struct CubeSat {
id: u64,
}
#[derive(Debug)]
enum StatusMessage {
Ok,
}
fn check_status(sat_id: CubeSat) -> CubeSat {
println!("{:?}: {:?}", sat_id, StatusMessage::Ok);
sat_id
}
fn main () {
let sat_a = CubeSat { id: 0 };
let sat_b = CubeSat { id: 1 };
let sat_c = CubeSat { id: 2 };
let sat_a = check_status(sat_a); #1
let sat_b = check_status(sat_b);
let sat_c = check_status(sat_c);
// "waiting" ...
let sat_a = check_status(sat_a);
let sat_b = check_status(sat_b);
let sat_c = check_status(sat_c);
}
Follow the complete CubeSat program to see ownership move into check_status and return to the original scope. section 4.4
Listing 10.13 Using a variable defined in a parent scope in multiple closures
1 use std::{thread,time};
2
3 fn main() {
4 let pause = time::Duration::from_millis(20);
5 let handle1 = thread::spawn(move || {
6 thread::sleep(pause);
7 });
8 let handle2 = thread::spawn(move || {
9 thread::sleep(pause);
10 });
11
12 handle1.join();
13 handle2.join();
14 }
Compare two spawned closures that use the same pause value and observe how move changes their captures. section 10.2.6




