====== Saturday, May 7th, 2022 ======
\\ \\ Think of a stack of plates: when you add more plates, you put them on top of the pile, and when you need a plate, you take one off the top. Adding or removing plates from the middle or bottom wouldn’t work as well! Adding data is called pushing onto the stack, and removing data is called popping off the stack The wonderful people at the [[https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html| RustDocs]]\\ All data on the stack **MUST** have a knows fixed size at compile time **Heap:** The heap is less organized. You request space. The memory allocator finds you some thats big enough and gives you a pointer to it ((allocating memory)). Since the pointer is always of a fixed size, you can store that in the stack.
\\ \\ Think of being seated at a restaurant. When you enter, you state the number of people in your group, and the staff finds an empty table that fits everyone and leads you there. If someone in your group comes late, they can ask where you’ve been seated to find you. the wonderful wonderful people at the [[https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html| RustDocs]]Pushing to the stack is faster <-> allocating to the heap is slower because it has to find memory rather than just //popping// it on top Reading values from the stack is faster, the computer knows how much to jump to the next memory location <-> Reading form the heap is slower as the computer((NOT [[https://en.wikipedia.org/wiki/Joseph_Schumpeter| Schumpeter]])) has to take the pointer and find it in the heap. The computer would rather work on data on the stack as it is so much faster and cooler.
\\ \\ When your code calls a function, the values passed into the function (including, potentially, pointers to data on the heap) and the function’s local variables get pushed onto the stack. When the function is over, those values get popped off the stack. umm if you don't know... now you know the wonderful wonderful people at the [[https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html| RustDocs]]\\ \\ == Ownership Rules == - Each value in Rust has a variable that is called its **OWNER** - There can be only one **OWNER** at a time - When the **OWNER** goes out of scope, the variable is dropped == Variable Scope == simple shit
{ // s is not valid here or before
let s = "yolo"; //s is not valid
//wow s your so cool cause we can use you for things here!
} //s has been dropped
see, simple.
== freeing memeory ==
When we request memory and are done with it. We must free it. Every allocate should be paired with one free of the memory.
Garbage collected languages scan for unused memory periodically and free it.
Big boi languages expect you to do it yourself.
**RUST DROPS THAT SHIT WHEN IT GOES OUT OF SCOPE**
== Move ==
With simple types that are stored on the stack. A copy of the data is made when we try to bind it to another variable. **This is a deep copy**
let x =2;
let y=x;
println!("{}",y);
println!("{}",x);
that will compile.
However with data stored on the Heap such as a string it would be to time consuming and expensive to run. So rust would just store the pointer to the data in the new variable.
\\
[[https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html|{{:devlogs:string_copy.png?200}}]]
But what if s1 goes out of scope first and the data gets dropped?????????? so when we do something like this rust will just "move" the refrence from s1 to s2 and s1 will go out of scope.
let s1 = String::from("Shaun");
let s2 = s1; // s1 has gone out of scope
println!("{} PauL",s2);
println!("{} FaiL",s1);
That will not compile.
[[https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html|{{:devlogs:string_move.png?200}}]]
by default none of rust's functions will **deep copy** any heap data so you can just assume that it **moves** it.
== Clone ==
If you did wanna **deep copy** heap data. You can clone it. Strings derive clone.
let s1 = String::from("hello");
let s2 = s1.clone();
println!("s1 = {}, s2 = {}", s1, s2); //Good job it compiles and you wasted memory!
//Copied from the rust book
== Copy ==
As with the simple int example above. Simple stack stored traits can be copied and used over again. Even structs that contain these copyable types can be copied. If a type inherits the **drop** trait it cannot be copied.
fn main() {
let s = String::from("hello"); // s comes into scope
takes_ownership(s); // s's value moves into the function...
// ... and so is no longer valid here
let x = 5; // x comes into scope
makes_copy(x); // x would move into the function,
// but i32 is Copy, so it's okay to still
// use x afterward
} // Here, x goes out of scope, then s. But because s's value was moved, nothing
// special happens.
fn takes_ownership(some_string: String) { // some_string comes into scope
println!("{}", some_string);
} // Here, some_string goes out of scope and `drop` is called. The backing
// memory is freed.
fn makes_copy(some_integer: i32) { // some_integer comes into scope
println!("{}", some_integer);
} // Here, some_integer goes out of scope. Nothing special happens.
//Copied from the rust book
Things that derive copy, get copied into a function. and droppable types get moved.
Returning stuff follows a similar rule.
fn main() {
let s1 = gives_ownership(); // gives_ownership moves its return
// value into s1
let s2 = String::from("hello"); // s2 comes into scope
let s3 = takes_and_gives_back(s2); // s2 is moved into
// takes_and_gives_back, which also
// moves its return value into s3
} // Here, s3 goes out of scope and is dropped. s2 was moved, so nothing
// happens. s1 goes out of scope and is dropped.
fn gives_ownership() -> String { // gives_ownership will move its
// return value into the function
// that calls it
let some_string = String::from("yours"); // some_string comes into scope
some_string // some_string is returned and
// moves out to the calling
// function
}
// This function takes a String and returns one
fn takes_and_gives_back(a_string: String) -> String { // a_string comes into
// scope
a_string // a_string is returned and moves out to the calling function
}
//Taken from the rust docs.. Again please read that. and not this...
S1 gets ownership from the functions return.
S2 is moved into the function and then is returend back to s3
~~DISCUSSION | Tell me the things I don't want to hear ~~