79 lines
2.6 KiB
Rust
79 lines
2.6 KiB
Rust
fn read(y: bool) {
|
|
if y {
|
|
println!("y is true!");
|
|
}
|
|
}
|
|
|
|
// Rust wants to ensure no undefined behavior at compile-time
|
|
// Sounds a lot like Haskell!
|
|
fn main() {
|
|
// read(x); // Moving read here would cause an error
|
|
let x = true;
|
|
read(x);
|
|
|
|
// -------------------------------------------------------------
|
|
// How variable live in the stack
|
|
|
|
let n = 5; // step 1: stack stores n = 5
|
|
let y = plus_one(n); // step 3: stack stores n = 5 and y = 6 now
|
|
println!("The value of y is: {y}");
|
|
|
|
// These variables live in frames
|
|
// The frame for main at step 1 holds n = 5
|
|
// Frame for plus_one at step 2 holds x = 5
|
|
// Frame for main at step 3 holds n = 5 and y = 6
|
|
//
|
|
// These frames get organized into a stack of currently-called-functions.
|
|
// At step 2, the frame for main sits above the frame for the called function, plus_one.
|
|
//
|
|
// For Rust to transfer access to data without copying it, it uses pointers.
|
|
// Pointers and pointees
|
|
// Rust can put data on the heap with Box.
|
|
// The stack holds data associated with specific functions while
|
|
// the heap holds data that can outlive a function.
|
|
|
|
// There is only one array in memory at a time with this method.
|
|
let a = Box::new([0; 1_000_000]);
|
|
let b = a;
|
|
// println!("first value of a {}", a[0]); // This code is invalid bc of borrowing from a
|
|
|
|
// Rust doesn't allow user memory management
|
|
|
|
// -------------------------------------------------------------
|
|
// Box's owner manages deallocation
|
|
|
|
// Almost how this works:
|
|
// When a variable is bound to a box, when Rust deallocates the variable's
|
|
// frame, then Rust deallocates the box's heap memory.
|
|
let a_num = 4;
|
|
make_and_drop();
|
|
|
|
// How this works fully (uses ownership):
|
|
// When variable owns a box, when Rust deallocates the variable's frame,
|
|
// then Rust deallocates the box's heap memory.
|
|
let d = Box::new([0; 1_000_000]); // d owns this Box here
|
|
let e = d; // e has ownership of the box transfered to it from d. Say it's moved
|
|
|
|
// Rust data structures like String, Vec, and HashMap use Boxes.
|
|
|
|
// Variables can't be used after moving
|
|
// Can use .clone() to avoid moving data
|
|
let first = String::from("Ferris");
|
|
let first_clone = first.clone();
|
|
let full = add_suffix(first_clone);
|
|
println!("{full}, originally {first}");
|
|
}
|
|
|
|
fn plus_one(x: i32) -> i32 {
|
|
x + 1 // step 2: stack stores n = 5 from main and x = 5 in this function
|
|
}
|
|
|
|
fn make_and_drop() {
|
|
let a_box = Box::new(5);
|
|
}
|
|
|
|
fn add_suffix(mut name: String) -> String {
|
|
name.push_str(" Jr. ");
|
|
name
|
|
}
|