modello legame può avere un po 'di utilizzare per;)
Per capire cosa fa il compilatore, è possibile utilizzare il let _:() = ...;
trucco. Assegnando a una variabile di tipo ()
, si forza il compilatore a stampare un messaggio di errore che fornisce il tipo che ha dedotto per la variabile.
Nel primo esempio:
let vec = vec![1, 2, 3];
let &y = &vec;
let _:() = y;
otteniamo:
<anon>:5:17: 5:18 error: mismatched types:
expected `()`,
found `collections::vec::Vec<_>`
(expected(),
found struct `collections::vec::Vec`) [E0308]
<anon>:5 let _:() = y;
^
<anon>:5:17: 5:18 help: see the detailed explanation for E0308
il tipo di y
è Vec<i32>
.
Che cosa significa è che siete:
- Prestito
vec
in una temporanea
- Cercando di spostare
vec
in y
, che è proibito perché vec
è già preso in prestito.
Il codice corretto equivalente sarebbe:
let vec = vec![1, 2, 3];
let y = vec;
Nel secondo esempio:
let vec = vec![1, 2, 3];
let ref y = &vec;
let _:() = y;
otteniamo:
<anon>:5:17: 5:18 error: mismatched types:
expected `()`,
found `&&collections::vec::Vec<_>`
(expected(),
found &-ptr) [E0308]
<anon>:5 let _:() = y;
^
<anon>:5:17: 5:18 help: see the detailed explanation for E0308
Quindi è &&Vec<i32>
.
Questo ci permette di vedere che let ref a = b;
è generalmente equivalente a let a = &b;
, e quindi in questo caso: let y = &&vec;
.
ref
è realizzato per destrutturazione; per esempio, se si ha:
let vec = Some(vec![1, 2, 3]);
if let Some(ref y) = vec {
}
si usa ref
qui per essere in grado di legarsi a y
senza muoversi anche se vec
ha qui Tipo Option<Vec<i32>>
. Infatti, lo scopo di ref
è di prendere un riferimento all'interno di un oggetto esistente durante la destrutturazione.
In generale, in un'istruzione let
, non verrà utilizzato ref
.
C'è un caso legit dove vogliamo usare qualcosa come 'Let & y = &vec;'? – WiSaGaN
@WiSaGaN: Non riesco a pensare a nessuno. –
@WiSaGaN: questa costruzione può essere utilizzata ad esempio nelle chiusure. È usato nella funzione di ritenzione in Vec e così via. –