rust - Variable binding: moving a &mut or borrowing the referent? -
this code fails expected @ let c = a; compile error "use of moved value: a":
fn main() { let a: &mut i32 = &mut 0; let b = a; let c = a; } a moved b , no longer available assignment c. far, good.
however, if annotate b's type , leave else alone:
fn main() { let a: &mut i32 = &mut 0; let b: &mut i32 = a; let c = a; } the code fails again @ let c = a;
but time different error message: "cannot move out of a because borrowed ... borrow of *a occurs here: let b: &mut i32 = a;"
so, if annotate b's type: no move of a b, instead "re"-borrow of *a?
what missing?
cheers.
so, if annotate
b's type: no move ofab, instead "re"-borrow of*a?what missing?
absolutely nothing, in case these 2 operations semantically similar (and equivalent if a , b belong same scope).
- either move reference
ab, makingamoved value, , no longer available. - either reborrow
*ainb, makingaunusable longbin scope.
the second case less definitive first, can show putting line defining b sub-scope.
this example won't compile because a moved:
fn main() { let a: &mut i32 = &mut 0; { let b = a; } let c = a; } but 1 will, because once b goes out of scope a unlocked:
fn main() { let a: &mut i32 = &mut 0; { let b = &mut *a; } let c = a; } now, question "why annotating type of b change behavior ?", guess be:
- when there no type annotation, operation simple , straightforward move. nothing needed checked.
- when there type annotation, conversion may needed (casting
&mut _&_, or transforming simple reference reference trait object). compiler opts re-borrow of value, rather move.
for example, code perflectly valid:
fn main() { let a: &mut i32 = &mut 0; let b: &i32 = a; } and here moving a b not make sense, of different type. still code compiles: b re-borrows *a, , value won't mutably available through a long b in scope.
Comments
Post a Comment