Ownership
Ownership prevents null ptrs and data races
Each value in Rust has an owner.
There can only be one owner at a time.
When the owner goes out of scope, the value is dropped.
Values can be moved between variables
Slices let you reference a contiguous sequence of elements in a collection rather than the whole collection
let x = 5;
let y = x;
println!("x = {x}, y = {y}"); //works fine, cuz on stack so fast
//different cuz on heap
let s1 = String::from("hello");
let s2 = s1;
println!("{s1}, world!"); //invalid bc since strings stored as ptr, rust auto declares s1 invalid
//instead
let s1 = String::from("hello");
let s2 = s1.clone();
println!("s1 = {s1}, s2 = {s2}");
calling functions auto pass ownership so no longer valid
fn main() {
let s1 = gives_ownership();
let s2 = String::from("hello");
let s3 = takes_and_gives_back(s2);
} // 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 {
let some_string = String::from("yours");
some_string
}
// This function takes a String and returns one
fn takes_and_gives_back(a_string: String) -> String {
a_string
}
References And Borrowing
references allow you to refer to some value without taking ownership of it
We call the action of creating a reference borrowing. As in real life, if a person owns something, you can borrow it from them. When you’re done, you have to give it back
fn main() {
let s1 = String::from("hello");
let len = calculate_length(&s1);
println!("The length of '{s1}' is {len}.");
}
fn calculate_length(s: &String) -> usize {
s.len()
}
Cant change
fn main() { let s = String::from("hello"); change(&s); } fn change(some_string: &String) { some_string.push_str(", world"); }// ERRORRRRR
To change make mut
Mutable references have one big restriction: if you have a mutable reference to a value, you can have no other references(either mut or not) to that value.
fn main() {
let mut s = String::from("hello");
change(&mut s);
}
fn change(some_string: &mut String) {
some_string.push_str(", world");
}
note ref scope goes from init to last time its used so
//will fail
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);
//fine
let mut s = String::from("hello");
let r1 = &s; // no problem
let r2 = &s; // no problem
println!("{r1} and {r2}"); // variables r1 and r2 will not be used after this point
let r3 = &mut s; // no problem
println!("{r3}");
rust will catch dangling ptrs
//will fail fn main() { let reference_to_nothing = dangle(); } fn dangle() -> &String { let s = String::from("hello"); &s }
Last updated