Perché posso restituire un riferimento a un letterale locale ma non a una variabile?

Perché questo codice viene compilato?

fn get_iter() -> impl Iterator { [1, 2, 3].iter().map(|&i| i) } fn main() { let _it = get_iter(); } 

[1, 2, 3] è una variabile locale e iter() prende in prestito. Questo codice non deve essere compilato poiché il valore restituito contiene un riferimento a una variabile locale.

Nel tuo esempio, [1, 2, 3] non è considerato come variabile locale, ma come statico!

Diamo un’occhiata a questo codice:

 fn foo() -> &'static [i32] { &[1, 2, 3] } 

Funziona!

Qualche tempo fa, RFC 1414: Rvalue Static Promotion è stato unito: “Promuovi constexpr rvalues ​​ai valori nella memoria statica invece che negli slot dello stack”. Ciò significa che sostanzialmente tutti i letterali che scrivi possono vivere per sempre. Quindi, cose come let _: &'static i32 = &42; anche lavorare!

Se evitiamo di utilizzare un array letterale, possiamo vedere l’errore previsto:

 fn bar() -> impl Iterator { vec![1, 2, 3].iter().map(|&i| i) } 

Qui otteniamo l’errore ” v non vive abbastanza a lungo”.

Questo non è limitato a numeri interi o array; si applica in generale:

 fn promote_integer() -> &'static i32 { &42 } fn promote_float() -> &'static f64 { &42.42 } fn promote_char() -> &'static char { &'c' }