https://google.github.io/comprehensive-rust/
https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer
TODO :
- automatic dereference
- concurrency
- smart pointer
Cheatsheet
&T &mut T Type: shared / mutable reference to type T
& &mut Operator: make a (mutable) reference value
* Operator: dereferences
*const T Raw pointer to immutable T
*mut T Raw pointer to mutable T
Reference
#![allow(unused)] fn main() { /// reference provides way to access another value without takine responsibility /// for the value aka. borrowing. Shared references are read-only and the /// referenced data cannot change. fn shared_references() { let a = 'A'; let b = 'B'; let mut r: &char = &a; println!("r: {}", *r); r = &b; // a mutable reference be changed to point to other data // but the refrenced data itself cannot change in this case. // DIFFERENT than C++ !! // shared reference does NOT allow modifying the value it refers to, // EVEN IF the value is mutable println!("r: {}", *r); // auto dereferences: use *r or r are the same. println!("r: {}", r); } /// exclusive aka mutable references, allow changing the value they refer to. /// they have type &mut T /// differentiate the two: /// let mut x_coord: &i32 /// let mut x_coord: &mut i32 fn exclusive_references() { // &mut T a exclusive (mutable) reference to type T // NO other (shared or exclusive) reference can exist at the same time // the referenced value cannot be accessed while the exclusive reference // exists let mut point = (1, 2); let x_coord = &mut point.0; *x_coord = 20; // point.0 = 0; // this is illegal while x_coord is alive println!("point: {point:?}"); } }
Smart Pointers
TODO finish this
Raw Pointers
#![allow(unused)] fn main() { fn raw_pointer() { let mut num:i32 = 5; // declaring raw pointers is safe. let ptr1 = &mut num as *mut i32; let ptr2 = &mut num as *mut i32; // both are valid pointer to // dereferencing raw pointers is unsafe unsafe { *ptr1 += 1; *ptr2 += 1; } println!("{}", num); // 7 let num:i32 = 5; // illegal because num is not mutable let ptr3 = &mut num as *mut i32; // illegal because the different type let ptr3 = &num as *const u32; // "legal" cast with indirection let ptr = &(r as u32) as *const u32; // casting and reading is legal let ptr_mut = ptr as *mut u32; // but dereferencing is illega even in unsafe // TODO learn UnsafeCell unsafe{ println!("{}", *ptr_mut); *ptr_mut ++; println!("{}", *ptr_mut); } // cast raw value into raw pointer: let addr:usize = 0xffff40; let wtf = unsafe{*(addr as *const u64)}; println!("{}", wtf); // segfault // TODO I think it's hackable to cast an address to usize, // then cast it to whatever you want. But it turns out that // &T as usize is illegal... are there other hacks? } }