I've some of the concepts of references, and that it solves multiple living-refences that would otherwise lead to double free, or to access de-allocated data.
In the case below, one isn't using references but just "following the pointers" with *. I'm aware that "pointer" isn't the best concept maybe, but idk what to use here.
I think the reason why the first one is not allowed is what I stated above (but may be wrong?)
However, I don't get why wouldn't the Box<T> behave the same. Instead it moves the data, or copies it if it's a number.
Is there a simple explanation? (up to beginning of chapter 5 this wasn't yet explained in the book, imho.)
fn main(){
dereferencing_cases();
}
fn follow_the_pointer_cases() {
let v = vec![String::from("meow")];
let y = *v[0]; // Does not or it could cause troubles (maybe double frees)
// or access data that has moved i.e v2[0]
let ss = Box::new(String::from("My String"));
let ss2 = *ss; // works fine, and moves the String!
println!("{ss2}")
// so println!("{ss:?}") would fail
}
(tbc: i'm aware we can just clone it as an option.)
Box is special; if x: Box<Something> then you can move a value out of *x, but it is the only type that supports this ability to move out of a dereference. The fact that Box is unique in this way is largely a historical accident — Box used to be even more magical than it is today, and no one has yet invented a solid plan for extending this to arbitrary other types.
v[0] already "follows" one pointer and refers to the memory location where the String. You're then trying to follow the pointer that the String represents (because it implements the Deref trait). However String points to a str, which is an "unsized" type, because a str could have any length, and so you can't follow it and move/copy it to a variable, because variable can only contain "sized" data, that is data whose type's size is known at compile time.
I encourage you to try the same but storing a Box<String> and/or Box<i32> in the Vec and seeing what happens.
You can not move elements out of a vector. The actual element type does not matter, moving an element out of a vector would leave a void hole, making the whole vector invalid. Think of a vector with n elements, moving an element with index < n out. There would be a hole.