On Borrowing

let x = 5; 
println!("{}", x); // prints 5
let y = 4;
println!("{}", y); // prints 4
let z = 3;
println!("{}", z); // prints 3
let x = 5; 
println!("{}", x); // prints 5
let x = 4;
println!("{}", x); // prints 4
let x = 3;
println!("{}", x); // prints 3
let until_shadow x = 5; 
println!("{}", x);
// "x" has been shadowed, so we can reclaim the old memory for something else
let until_shadow x = 4;
println!("{}", x);
// "x" has been shadowed again, so we can reclaim the second value let until_shadow x = 3;
println!("{}", x);
let until_shadow x = 5; 
let y = &x; // we take a reference to x here
println!("{}", x);
let until_shadow x = 4; // ERROR!!!
// y still references the old value, so it is an error to reclaim
// x's memory.
println!("{}", x);
let until_shadow x = 3; println!("{}", x);
let until_shadow x = 5; 
let unique_ref y = &x;
println!("{}", y);
// We have told the compiler that y is the only way to access x, so // we should not access it directly.
// println!("{}", x); // ERROR!
let until_shadow x = 4;
// At this point we can reclaim the old value. We have shadowed
// the old reference, so the old reference is no longer accessible.
// The old reference was the only way to access the old value so
// we should be able to use the old value's memory for something
// else.
let unique_ref y = &x;
println!("{}", y);
let until_shadow x = 3;
let unique_ref y = &x;
println!("{}", y);
let mut x = 5; 
let mut y = &x;
println!("{}", y);
// We have told the compiler that y is the only way to access x, so // we should not access it directly:
// println!("{}", x); // ERROR!
// We create a new reference and a new value at the same time.
// We can safely overwrite the old value and the old reference
// because their names have been shadowed. The net result is
// that only the value has changed.
*y = 4;
println!("{}", y);
*y = 3;
println!("{}", y);
  • Consider all variables in rust to be immutable, and all references to be immutable references.
  • We do not mutate variables, we just create new ones.
  • If we cannot modify a variable, we can never have data races.
  • If a variable has a valid reference to itself, we cannot safely overwrite the variable’s memory with something else. (Explains immutable borrows)
  • A mut annotation on a reference indicates that it is the only way to access a variable. (Explains why you cannot borrow mutably and immutably at the same time, explains why you can only have a single mutable borrow)
  • A mut annotation on a variable indicates that the memory may be overwritten if there is a unique reference to it and that unique reference is shadowed, or if there are no references to it, and the variable itself is shadowed. (Explains mutable borrows)

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Andrew Pritchard

Andrew Pritchard

The stories I write are a part of a learning journey through life, logic and programming. Share this journey with me.