I appreciate this is "for C++ programmers" but as a Python programmer I'm still interested.
I'm trying to figure out why destructuring something into multiple variables causes problems for move semantics. It seems to me that if you have an object with move semantics in a particular area of memory, and you tell the compiler "I wish to use the name X to refer to this field, and the name Y to refer to that field", that should be fine - as long as you don't store a reference to those fields, or pass them to somebody else (the usual restrictions of borrowed code). The compiler already knows that some names refer to allocations on the stack or the heap, it seems like you should be able to add new names for existing variables at compile-time (as opposed to runtime, using pointers which would add all the horrible borrowing issues Rust tries to avoid).
Is it really just that when you create a new name, the compiler has to create a new allocation to back it, even if it would require making a redundant copy of the interesting data?
You can destructure without moving, as you suggest, by taking a reference.
Move:
let x = (box 2u, box 4u);
let (y, z) = match x {
(first, second) => (first, second)
};
println!("x is {}", x);
// this will not compile: x is moved into y and z
Reference:
let x = (box 2u, box 4u);
let (y, z) = match x {
(ref first, ref second) => (first, second)
};
println!("x is {}", x);
// this works fine
Destructuring doesn't cause problems for move semantics, it's that move semantics restrict the ways in which you can destructure an object.
Essentially, if you're trying to destructure a borrowed object, you have to use references. If instead you tried to destructure its fields into owned objects, this would involve moving the field in the borrowed object into your owned object, except you're not allowed to destroy borrowed objects.
For further clarification, when you say "I wish to use the name X to refer to field Y", that's a reference (X refers to Y).
I'm trying to figure out why destructuring something into multiple variables causes problems for move semantics. It seems to me that if you have an object with move semantics in a particular area of memory, and you tell the compiler "I wish to use the name X to refer to this field, and the name Y to refer to that field", that should be fine - as long as you don't store a reference to those fields, or pass them to somebody else (the usual restrictions of borrowed code). The compiler already knows that some names refer to allocations on the stack or the heap, it seems like you should be able to add new names for existing variables at compile-time (as opposed to runtime, using pointers which would add all the horrible borrowing issues Rust tries to avoid).
Is it really just that when you create a new name, the compiler has to create a new allocation to back it, even if it would require making a redundant copy of the interesting data?