From a316a2ae8d51f24e0d0ae16861becc1c4d191133 Mon Sep 17 00:00:00 2001 From: Rowan Torbitzky-Lane Date: Wed, 19 Mar 2025 17:01:37 -0500 Subject: [PATCH] ch4.2 wip --- ch4/refs_and_borrow/src/main.rs | 52 +++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/ch4/refs_and_borrow/src/main.rs b/ch4/refs_and_borrow/src/main.rs index 705c23c..6d8533d 100644 --- a/ch4/refs_and_borrow/src/main.rs +++ b/ch4/refs_and_borrow/src/main.rs @@ -5,21 +5,67 @@ fn main() { // greet(m1, m2); // let s = format!("{} {}", m1, m2); - // This is suboptimal + // This is suboptimal due to verboseness of solution let m1 = String::from("Hello"); let m2 = String::from("World"); let (m1_again, m2_again) = greet_ret(m1, m2); let s = format!("{} {}", m1_again, m2_again); println!("{s}"); - // stopped here: - // https://rust-book.cs.brown.edu/ch04-02-references-and-borrowing.html#references-are-non-owning-pointers + // references make a convenient usage of ownership + // Can now use mm1 and mm2 later after the call to greet_ref + // References are non-owning pointers. + let mm1 = String::from("Hello"); + let mm2 = String::from("World"); + greet_ref(&mm1, &mm2); + let ss = format!("{} {}", mm1, mm2); + println!("{ss}"); + + // ----------------------------------------------------------------------------- + // Dereferencing a pointer accesses it data + + // Rust often implicitly inserts references and dereferences throughout + // the code; ergo, won't see * often in Rust code + // This can be seen in str::len + + let mut x: Box = Box::new(1); + let a: i32 = *x; // reads heap value, so a stores 1 not following x + *x += 1; // *x points to value on heap, now adds 1 to x + println!("{}", *x); + + let r1: &Box = &x; // r1 points to x on the stack + let b: i32 = **r1; // two dereferences get the heap value + println!("{}", b); + + let r2: &i32 = &*x; // r2 points to heap value directly. Making a new reference to the deferenced i32 + let c: i32 = *r2; // one dereference needed to read it + + // ----------------------------------------------------------------------------- + // Rust avoids simultaneous aliasing and mutation + // + // Aliasing: accessing same data through different variables + // aliasing on its own okay. Combining with mutation allows "rug pulling" from other variables + + // Invalid code: + // let mut v: Vec = vec![1, 2, 3]; + // let num: &i32 = &v[2]; + // v.push(4); + // println!("3rd element is {}", *num); // undefined behavior here + + // 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 } fn greet(g1: String, g2: String) { println!("{} {}!", g1, g2); } +fn greet_ref(g1: &String, g2: &String) { + println!("{} {}!", g1, g2); +} + fn greet_ret(g1: String, g2: String) -> (String, String) { println!("{} {}!", g1, g2); (g1, g2)