Hi,
I am picking up rust again, but I am really confused about basic things.
For instance:
let v = vec![String::from("hello"), String::from("world")];
let s = &v[0]; // 1
How does rust (compiler) evaluate &v[0] ? Where does the borrow checker comes in and say "Ok, you're good" or "nope" ?
I mean v[0] would not pass the borrow checker as you cannot move a String out of a vector right ? But for evaluating &v[0] don't you have to first evaluate the operator of the reference operator ?
Is v[0] still a place expression when v is a vector ?
Sorry, I am not sure my question makes sense..
container[index] is actually syntactic sugar for *container.index(index)
You can also see from the trait docs that the method index always returns a reference. Thus, by using & in here, you effectively write the following code:
let v = vec![String::from("hello"), String::from("world")];
let s = &*v.index(0); // 1
This constitutes a reborrow, but you can essentially imagine that the & and * cancel each other out, making this equivalent to just calling index. The important thing to notice is that * (at least for the borrow checker) does not eagerly take ownership of the value being referred to (sometimes that wouldn't even be possible) - this is also why you can turn a Strings into a &str via &*s.
Ooh, indeed, dereference expressions are place expression.
And in let s = v[0] it is evaluated in a value expression context, hence denotes the value held in the memory location represented by the place expression; while in let r = &v[0]v[0] is evaluated in a place expression context hence only reference the memory location, correct ?