Rust Programming ================ Object Ownership and Moving --------------------------- Memory un-safety and bugs usually come from dynamically allocated objects on the heap that are not successfully reclaimed (memory leak), or is freed more than once. The solution that Rust has come up with is the idea of ownership, where you can't have multiple variables reference the same heap objects simultaneously This trivial example shows how a heap object (or value) can be moved from one variable to another .. code-block:: rust fn main(){ //allocates a dynamic, mutable string on the heap let mut s1 = String::new(); //here s1 can be used and modified // object (value) to be moved from s1 to s2 let mut s2 = s1; //here s1 is no longer a valid reference to the object //here s2 goes out of scope, and heap memory reclaimed } This less trivial example shows how ownership can be moved into an out of function calls .. code-block:: rust fn main(){ //allocate object on the heap let s1 = String::new(); //declare an uninitialized String variable let s2: String; //moving ownership to the function, then function moves ownership back to variable s2 s2 = add_data(s1); //variable s1 no longer a valid reference to the object //s2 goes out of scope, and memory gets reclaimed } fn add_data(st: String) -> String { st.push_str("Some Data"); return st; } Object Borrowing and References ------------------------------- Passing a reference to an object doesn't move ownership. There are two kinds of reference passing * Passing an immutable reference * Passing a mutable reference Here is an example of both .. code-block:: rust fn main() { //heap object let mut s1 = String::new(); borrow_and_modify(&mut s1); //here s1 is still valid, as ownership was never moved, only borrowed borrows_object(&s1); } // here s1 goes out of scope, and thus destroyed and reclaimed // declared to borrow an object that would be mutated fn borrow_and_modify(st: &mut String){ st.push_str("Adding some Data"); } // declared to borrow an object that would not be mutated in anyway fn borrows_object(st: &String){ println!("sring length is {}",st.len()); } Notice where the ``mut`` keyword needs to be used #. In variable declaration, to indicate that the object is mutable #. In the declaration of a borrowing function params that would be mutated within the function #. When passing a reference to an object to a borrowing function that intends to mutate the object Primative Borrowing and dereferencing ------------------------------------- Since primative types are generally stored on the stack, and can easily and cheaply be copied, they need to be dereferenced when being passed and mutated within functions .. code-block:: rust fn main() { let mut x: u8 = 0; //needs to be declared mutable increment(&mut x); //pass a mutable reference to a borrowing function println!("current value: {}",x); } //defines a borrowing function that mutates a primitive fn increment(d: &mut u8){ *d = *d + 1; //dereferencing is required here }