# OWNERSHIP Rules that determine how memory is accessed. Compile-time check to make sure memory is being used as it should. ## Stack - Heap **Stack** Last In - First out Like a vector -> Put in the back, pop from the back Must be of known size to be used in Stack **Heap** Put things somewhere it fits -> Returns a *pointer* to that address **Summary** The less you have to go to heap better -> Heap is slow to put things and slow to get things ## RULES - Each value has a variable called *owner* - Only 1 simultaneous *owner* - If *owner* gets out of scope, value is dropped ### Variable Scope Same as C/C++, localized between a set of `{}` depends its validity ### String String literals (str) are constant strings known at runtime `String` struct is mutable and variable, thus stored in the heap because of unknown size `String` has a pointer to heap memory In rust, this pointer is passed around instead of copied So if you copy a string, by default hte previous owner loses ownership of the heap memory. Then when each variable goes out of scope, it cleans the memory it owns. ### HEAP Variable - Data Interaction: CLONE By default, each copy is a move (shallow copy), memory ownership is passed not copy of memory address or copy of actual heap data. If we want to duplicate the heap data and assign it again to another variable, that is `.clone` ### Stack Data Interaction: default copy When data is in the stack, the data is copied, because it is free as size is known at compile time. If a `data_type` has the `Copy` trait, then it behaves like a stack variable. By default assignation is copy leaving it valid instead of passing ownership. Contrary to `Drop` trait which is the trait to clean heap memory. - Integers, Booleans, Flaots, Characters, Tuples of `Copy` only types # Ownership and Functions The same as before. If a function uses a `Drop` argument, the ownership is then passed down to the function so code that still execute it out of function will not have valid access until function is returned. `Copy` Arguments are copied down to the function, so they stay valid. ## Return Values and Scope Return values can also return ownership of a variable. A function returning a `String` returns the ownership of the heap memory besides the copy of the pointer type. But if we give ownership and don't return it, then that memory is `Drop`ped, you can return it using tuples so we get back not only the intended return type but also the ownership of the variables we passed. But that is too much damn job -> `REFERENCES` give use permission but not ownership # References and Borrowing Just add `&` before the type when adding an argument Add `&` when passing the variable In this case, just has access to the original variable but does not take care of its memory so it gets no ownership. You can derefence and get a copy and thus ownership of the memory with `*` like in `C/C++` Like variable definition `&` references are const by default, you need to add `mut` behind `&` to allow it to change it. But you can only have 1 mutable reference to it at a time. Even the original variable will to have premission to change it as it's mutability is currently being used by a reference. ``` let mut s = String::from("hello"); let r1 = &mut s; let r2 = &mut s; // Oh No, double mutable access println!("{}, {}. {}", r1, r2, s); // r1 is valid // r2 was already not valid // s is now not valid as is currently being mutably borrowed by r1 ``` ``` let mut s = String::from("hello"); let r1 = &s; // no problem let r2 = &s; // no problem let r3 = &mut s; // BIG PROBLEM println!("{}, {}, and {}", r1, r2, r3); ``` You can't get access to the variable if it is already being borrowed, be it immutable or mutable borrow. But you can get infinite IMMUTABLE borrows if the variable is not being borrowd in mutable state ## Dangling References We can't, once memory is out of scope it is cleaned and compiler knows that so it does not allow to return ownership of a variable that would be cleaned. ``` fn dangle() -> &String { // dangle returns a reference to a String let s = String::from("hello"); // s is a new String &s // we return a reference to the String, s } // Here, s goes out of scope, and is dropped. Its memory goes away. // Danger! ``` You should return a copy of it, it will then send back the ownership of the memory, not the reference to the owner which does not transfer ownership. # The Slice Type Slice is a reference to a subset of a collection ``` let s = String::form("Hello world!"); let hello = &s[0..5]; ``` In this example we are referencing the first 5 chars form the value index. You can not write the 0 if your Range starts at 0, just `..5`. The same for the end `6..` will do from index 6 to end. ## String Literals String literals are written in the binary, variables that make use of a string literal are really a slice of the binary pointing to where the string resides and its length. ## Other Slices We can slice any other type of collection, like arrays.