Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any difference between partially moved values and moved values in Rust?

Currently in Rust master (0.10-pre), when you move one element of a unique vector and try to move a different element, the compiler complains:

let x = ~[~1, ~2, ~3];
let z0 = x[0];
let z1 = x[1]; // error: use of partially moved value: `x`

This error message is somewhat different from if you were to move the entire vector:

let y = ~[~1, ~2, ~3];
let y1 = y;
let y2 = y; // error: use of moved value `y`

Why the different message? If x is only "partially moved" in the first example, is there any way to "partially move" different parts of x? If not, why not just say that x is moved?

like image 931
nham Avatar asked Nov 01 '22 06:11

nham


1 Answers

If x is only "partially moved" in the first example, is there any way to "partially move" different parts of x?

Yes, there is, but only when you move these parts all at once:

let x = ~[~1, ~2, ~3];
match x {
    [x1, x2, x3] => println!("{} {} {}", *x1, *x2, *x3),
    _ => unreachable!()
}

It can be easily observed that xNs are really moved out because if you add additional line after the match:

println!("{:?}", x);

The compiler will throw an error:

main3.rs:16:22: 16:23 error: use of partially moved value: `x`
main3.rs:16     println!("{:?}", x);
                                 ^
note: in expansion of format_args!
<std-macros>:195:27: 195:81 note: expansion site
<std-macros>:194:5: 196:6 note: in expansion of println!
main3.rs:16:5: 16:25 note: expansion site
main3.rs:13:10: 13:12 note: `(*x)[]` moved here because it has type `~int`, which is moved by default (use `ref` to override)
main3.rs:13         [x1, x2, x3] => println!("{} {} {}", *x1, *x2, *x3),
                     ^~
error: aborting due to previous error

This is also true for structures and enums - they also can be partially moved.

like image 100
Vladimir Matveev Avatar answered Jan 04 '23 15:01

Vladimir Matveev