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 ofa
b
, 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
a
b
, makinga
moved value, , no longer available. - either reborrow
*a
inb
, makinga
unusable longb
in 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