Skip to content

Instantly share code, notes, and snippets.

@ChunMinChang
Created July 16, 2018 23:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ChunMinChang/ac1f00e3521755814714436a80d72003 to your computer and use it in GitHub Desktop.
Save ChunMinChang/ac1f00e3521755814714436a80d72003 to your computer and use it in GitHub Desktop.
Borrowed pointers learning notes.
// Summary:
//
// immutable : read-only privilege
// mutable : read-write privilege
//
// 1. A read-only(immutable) vairable cannot be casted to a read-write(mutable) variable.
// 2. One variable can be read by multiple instances, no matter what its type is.
// 3. If one mutable variable is under writting, no other can read or write it.
// 4. If one variable is under reading, no other can write it.
//
// I:
// immutable reference to immutable value => OK
// immutable reference to mutable value => OK
// mutable reference to immutable value => Not OK!
// mutable reference to mutable value => OK
//
// II:
// let (mut) p = 10;
// let (mut) q = &(mut) p;
// There is 2^3 = 8 possible declarations, with or without `mut`, for (p, q).
//
// III:
// there is 4 possible declarations for `let (mut) q = &(mut) p`:
// 1) let q = &p;
// q is a immutable pointer, pointing to a immutable value located at p.
// 2) let q = &mut p;
// q is a immutable pointer, pointing to a mutable value located at p.
// 3) let mut q = &p;
// q is a mutable pointer, pointing to a immutable value located at p.
// 4) let mut q = &mut p;
// q is a mutable pointer, pointing to a mutable value located at p.
//
// By I, if p isn't mutable, then 2, 4 fails.
// Therefore, in the cases mentioned in II, we will only have 6 cases:
// All 4 cases in III for a mutable p, and
// 2 cases(1 and 3 in III) for a immutable p.
// Test:
// 1) read
// 2) write
// 3) reassign
fn main() {
let x = 5;
let mut y = 6;
{
// r is immutable (immutable reference):
// r is a immutable pointer, pointing to a immutable value.
let r = &x;
// 1) read:
// x can be read by multiple instances at the same time
// since no one is writting value to x (and x is immutable).
let a = &x;
let b = &x;
// 2) write:
// *r = 5; // Fail: immutable reference cannot write value(and x is immutable)!
// 3) reassign:
// let r = &y; // Fail: r is immutable!
}
// Fail: x is immutable so we cannot borrow it mutably!
// That is, a read-only value cannot be written!
// {
// // r is immutable (mutable reference):
// // r is a immutable pointer, pointing to a mutable value.
// let r = &mut x;
// }
{
// r is mutable (immutable reference):
// r is a mutable pointer, pointing to a immutable reference.
let mut r = &x;
// 1) read:
// x can be read by multiple instances at the same time
// since no one is writting value to x (and x is immutable).
let a = &x;
let b = &x;
// 2) write:
// *r = 5; // Fail: immutable reference cannot write value(and x is immutable)!
// 3) reassign:
r = &y; // r is mutable so we can reassigne it as another mutable (immutable reference)
// *r = 5; // Fail: immutable reference cannot write value(and x is immutable)!
// y cannot be written since it's read by r.
// y = 10;
}
// Fail: x is immutable so we cannot borrow it mutably!
// That is, a read-only value cannot be written!
// {
// // r is a mutable (mutable reference):
// // r is a mutable pointer, pointing to a mutable value.
// let mut r = &mut x;
// }
{
// r is a immutable (immutable reference):
// r is a immutable pointer, pointing to a immutable value (even y is mutable).
let r = &y;
// 1) read:
// y can be read by multiple instances at the same time
// since no one is writing value to y (even y is mutable).
let a = &y;
let b = &y;
// y cannot be written since it's read by r.
// y = 10;
// That is, we cannot write value into y when others are reading y.
// The memory is locked when someone is reading.
// 2) write:
// *r = 10; // Fail: immutable reference cannot write value(even y is mutable)!
// From the error message, we learn that
// 1. a mutable value (y) can be immutably referenced (by r)!
// 2. a read-only(immutable) value cannot be written(mutable)!
// 3) reassign:
// r = &x; // Fail: r is immutable!
}
{
// r is a immutable (mutable reference):
// r is a immutable pointer, pointing to a mutable value.
let r = &mut y;
// 1) read:
// y cannot be read since it may be written by r!
// let a = &y;
// That is, y cannot be read since it may be under writting.
// y cannot be used now since y's memory is under writing by r.
// y = 10;
// 2) write:
// Writing value to r.
*r = 10;
// 3) reassign:
// Fail:
// 1. types differ in mutability, r shoud point to a mutable reference.
// 2. r is immutable so it cannot be reassigned.
// r = &x;
// Fail:
// 1. x cannot be borrowed mutably and
// 2. r is immutable so it cannot be reassigned.
// r = &mut x;
}
{
// r is mutable (immutable reference)
// r is a mutable pointer, pointing to a immutable value.
let mut r = &y;
// 1) read:
// y can be read by multiple instances at the same time
// since no one is writing value to y (even y is mutable).
let a = &y;
let b = &y;
// 2) write:
// *r = 10; // Fail: immutable reference cannot write value(even y is mutable)!
// 3) reassign:
r = &x; // r can be reassigned since it's mutable.
// x can be read by multiple instances at the same time
// since no one is writing value to x (and x is immutable).
let c = &x;
let d = &x;
// r = &mut x; // Fail: x cannot be borrowed mutably.
// ** Fail **:
// y cannot be used since it's borrowed to r at first in this block!
// Even we comment `let a/b = &y;` (no one is reading y right now),
// y is still unable to be written. Once y is borrowed, it lose its
// write privilege until finishing borrowing.
// y will be able to get write privilege back when program goes out
// from this block.
// y = 100;
}
{
// r is mutable (mutable reference)
// r is a mutable pointer, pointing to a mutable value.
let mut r = &mut y;
// 1) read:
// y cannot be read since it may be under writting by r!
// let a = &y;
// 2) write:
*r = 30;
// 3) reassign:
// Fail: Types differ in mutability. r shoud point to a mutable reference,
// but &x is a immutable pointer.
// r = &x;
// r = &mut x; // Fail: x is immutable!
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment