Non ho trovato alcuna regola nella documentazione di Rust che spiegherebbe come l'elisione a vita si applica alle chiusure. Facciamo un semplice esempio:Perché Rust non può dedurre la durata corretta in chiusure semplici, o perché sono in conflitto?
fn foo(s: &str) {
let id = |x: &str| x;
println!("{}", id(s));
}
fn main() {
foo("string");
}
ho pensato che la chiusura nella funzione foo
avrebbe funzionato simile al seguente codice:
fn foo(s: &str) {
struct Id; // A helper structure for closure
impl Id {
fn id(self: Self, x: &str) -> &str { &x }
}
let id = Id; // Creating a closure
println!("{}", id.id(s));
}
Quest'ultimo funziona bene, ma il primo non riesce a compilare e produce un messaggio di errore lungo sui requisiti di durata contrastanti:
t3.rs:2:24: 2:25 error: cannot infer an appropriate lifetime due to conflicting requirements [E0495]
t3.rs:2 let id = |x: &str| x;
^
t3.rs:2:24: 2:25 note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the block at 2:23...
t3.rs:2 let id = |x: &str| x;
^
t3.rs:2:24: 2:25 note: ...so that expression is assignable (expected `&str`, found `&str`)
t3.rs:2 let id = |x: &str| x;
^
<std macros>:3:11: 3:36 note: but, the lifetime must be valid for the expression at 3:10...
<std macros>:3 print ! (concat ! ($ fmt , "\n") , $ ($ arg) *)) ;
^~~~~~~~~~~~~~~~~~~~~~~~~
<std macros>:2:25: 2:56 note: in this expansion of format_args!
<std macros>:3:1: 3:54 note: in this expansion of print! (defined in <std macros>)
t3.rs:3:5: 3:27 note: in this expansion of println! (defined in <std macros>)
<std macros>:3:11: 3:36 note: ...so type `(&&str,)` of expression is valid during the expression
<std macros>:3 print ! (concat ! ($ fmt , "\n") , $ ($ arg) *)) ;
^~~~~~~~~~~~~~~~~~~~~~~~~
<std macros>:2:25: 2:56 note: in this expansion of format_args!
<std macros>:3:1: 3:54 note: in this expansion of print! (defined in <std macros>)
t3.rs:3:5: 3:27 note: in this expansion of println! (defined in <std macros>)
error: aborting due to previous error
mi chiedo perché ruggine non può dedurre la durata appropriata nelle chiusure semplici come quello che Ho scritto sopra. Inoltre, perché il compilatore pensa che ci siano in conflitto con i requisiti per tutta la vita.
Rimuovere il ': & str' e funziona. Il '& str' là non significa quello che pensi che significhi. Non ho tempo di spiegare ora, tuttavia, dato che dovrei essere a letto. –
In realtà intendevo "& str", perché è necessario in un caso un po 'più complesso. In ogni caso, la mia domanda non era come ottenere questo semplice esempio per funzionare, ma quali sono le regole qui? Perché il compilatore trova qui i requisiti in conflitto? – svat
@ChrisMorgan: Se avete tempo, sarebbe bello se poteste spiegare cosa sta succedendo. Ho la sensazione che potrebbe essere dovuto a un 'dedotto 'per <'a>' ma non è abbastanza chiaro ... e la mancanza di risposta dopo 20 ore sembra significare che non sono l'unico incerto di cosa sta succedendo ^^ –