diff --git a/ch4/refs_and_borrow/src/main.rs b/ch4/refs_and_borrow/src/main.rs index 6d8533d..5be8cb2 100644 --- a/ch4/refs_and_borrow/src/main.rs +++ b/ch4/refs_and_borrow/src/main.rs @@ -54,8 +54,54 @@ fn main() { // Data in Rust should never be aliased and mutated at the same time - // Stopped here: - // https://rust-book.cs.brown.edu/ch04-02-references-and-borrowing.html#references-change-permissions-on-places + // ----------------------------------------------------------------------------- + // References Change Permissions on Places + // + // Read (R): Data can be copied to another location + // Write (W): Data can be mutated + // Own (O): Dta can be moved or dropped + // These permissions only exist in the compiler, not at runtime. + // Default permission are RO, mut makes W + // References can temporarily remove these permissions. + // Permissions are defined on places and not just variables + // A place being anything to the left of the = sign + // Variables like a, Dereferences like *a, array accesses like a[0] + + // ----------------------------------------------------------------------------- + // Borrow checker finds permissions violations + + // Anytime a place is used, Rust expects that place to have certain + // permissions depending on the operation + + // ----------------------------------------------------------------------------- + // mutable references provide unique and non-owning access to data + + let mut v: Vec = vec![1, 2, 3]; + let num: &mut i32 = &mut v[2]; + *num += 1; + println!("Third element is {}", *num); // actually changes the 2nd element + println!("Vector is now {:?}", v); + + // temporarily "downgrade" to a read-only reference + let mut v: Vec = vec![1, 2, 3]; + let num: &mut i32 = &mut v[2]; + let num2: &i32 = &*num; + println!("{} {}", *num, *num2); + + // ----------------------------------------------------------------------------- + // Permissions are returned at the end of a references lifetime + + let mut x = 1; + let y = &x; + let z = *y; + x += z; + println!("final x val: {x}"); + + // ----------------------------------------------------------------------------- + // Data must outlive all of its references + + // Ended at: + // https://rust-book.cs.brown.edu/ch04-02-references-and-borrowing.html#summary } fn greet(g1: String, g2: String) { @@ -70,3 +116,24 @@ fn greet_ret(g1: String, g2: String) -> (String, String) { println!("{} {}!", g1, g2); (g1, g2) } + +fn ascii_capitalize(v: &mut Vec) { + let c = &v[0]; // *v has permissions R, W taken away + if c.is_ascii_lowercase() { + let up = c.to_ascii_uppercase(); // *v has permissions R, W is given + v[0] = up; + } else { + // *v has R, W is given + println!("Already Capitalized {:?}", v); + } +} + +fn first(strings: &Vec) -> &String { + // This function introduces the flow permission, F. + // F doesn't change throughout the body of a function + let s_ref = &strings[0]; + s_ref +} + +// Doesn't know whether &String is a reference to either strings or default +// fn first_or(strings: &Vec, default: &String) -> &String {}