Created
July 16, 2018 23:41
-
-
Save ChunMinChang/ac1f00e3521755814714436a80d72003 to your computer and use it in GitHub Desktop.
Borrowed pointers learning notes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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