- Stack = LIFO and is hella fast
- All data on the stack must take up a known, fixed size
- Basic data types (ints, bools, etc.) are all stored on the stack because they have a fixed size
- More complex data types of unknown size get stored on the heap
- Each value in rust has a variable that's called its owner
- There can be only one owner at a time
- When the owner goes out of scope, the value will be dropped (i.e. 'popped' off the stack)
- Memory is
free
d when the owner goes out of scope
- When this occurs, rust automatically calls the data type's
drop
function
# move
let s1 = String::from("hello");
let s2 = s1; // s1 has "moved" to s2, thus s1 is now deemed invalid and can't be used anymore
println!("{}", s2") // this is allowed,
println!("{}", s1") // this is not allowed because s1 is now invalid
- A "move" can be thought of as a shallow copy - the actual string contents on the heap is not copied
- Side note - rust never automatically creates deep copies of data
- So copying stuff is always super inexpensive!
# clone
let s1 = String::from("hello");
let s2 = s1.clone();
println("{} {} ", s1, s2) // this is ok in this instance because we cloned everything into s2
# String literal - immutable - stack - string must be known at compile time
let s = "I am a string literal";
# `String` type - mutable - heap - can shrink/grow as needed
let s = String::new();
let mut s2 = String::from("I am a mutable String type, change me if you want to");
# String reference - a refernce to a `String` - the reference does not "own" the String
let s = String::new();
some_function_that_doesnt_need_to_mutate_a_string(&s);
# Mutable String reference - a mutable reference to a `String`
let mut s = String::new()
some_function_that_does_need_to_mutate_a_string(&mut s);
# String slice - a reference to part of a `String`
let s = String::from("I am string");
println!("here's part of the String: {}", &s[0..1]);
- The
String
data type consists of:
- A pointer to the memory that holds the contents of the string
- Length (how much memory in bytes the contents of the
String
is currently using)
- Capacity (total amount of memory in bytes that the
String
has received from the OS)
- These 3 things get stored on the stack, the data pointed at by the pointer is on the heap
- When writing a function that accepts a reference to a
String
, it is usually best to accept a string slice instead
- This allows string literals, slices of string literals and slices of
String
s to be passed, not just String
s