Binding to a template may get some use;)
To understand what the compiler does, you can use let _:() =...; trick. By assigning a variable of type () , you force the compiler to print an error message, telling you the type deduced for your variable.
In the first example:
let vec = vec![1, 2, 3]; let &y = &vec; let _: () = y;
we get:
error[E0308]: mismatched types --> src/lib.rs:4:13 | 4 | let _: () = y; | ^ expected (), found struct 'std::vec::Vec' | = note: expected type '()' found type 'std::vec::Vec<{integer}>'
type y is Vec<i32> .
This means that you:
- Borrowing
vec in temporary - Trying to move
vec to y , which is forbidden because vec already taken.
The equivalent correct code would be:
let vec = vec![1, 2, 3]; let y = vec;
In the second example:
let vec = vec![1, 2, 3]; let ref y = &vec; let _: () = y;
we get:
error[E0308]: mismatched types --> src/lib.rs:4:17 | 4 | let _: () = y; | ^ expected (), found reference | = note: expected type '()' found type '&&std::vec::Vec<{integer}>'
So y &&Vec<i32> .
This let's see that let ref a = b; usually equivalent to let a = &b; and therefore, in this case: let y = &&vec; ,
ref made for restructuring; for example, if you had:
let vec = Some(vec![1, 2, 3]); if let Some(ref y) = vec { // use 'y' here }
here you can use ref to be able to bind y to &Vec<i32> without moving, even if here vec is of type Option<Vec<i32>> . Indeed, the purpose of ref is to obtain a link inside an existing object during destructuring.
In the general case, in the let expression, you will not use ref .