Ciò richiede higher rank trait bounds, in particolare, le durate di rango superiore. La sintassi completa su unsugared sarebbe F: for<'a> FnOnce<(&'a mut Builder,),()>
.
L'utilizzo di una durata della funzione non può funzionare, ad es. se avessimo
pub fn build<'b, F>(rules: F) -> Builder where F: FnOnce<(&'b mut Builder,),()>
Questo dice che build
lavori con qualunque durata del chiamante desidera (ad esempio, potrebbero scelto 'b
== 'static
), ma questo non è valido, perché non v'è una vita concreta specifica che deve essere utilizzato il : la durata del &mut builder
all'interno della funzione. L'utilizzo di F: for<'a> ...
in un limite dice che F
funziona con qualsiasi durata 'a
, quindi il compilatore vede che è legale sostituire in quello di &mut builder
.
Come ho accennato sopra, questa è la sintassi unsugared davvero brutta. Ci sono due modi in cui questo può essere reso molto più bello. In primo luogo, il modo canonico per utilizzare i tratti di chiusura è lo zucchero ()
: for<'a> FnOnce(&'a mut Builder) ->()
oppure, come nel resto di Rust, è possibile eliminare lo ->()
: for<'a> FnOnce(&'a mut Builder)
. (. NB: questo è solo zucchero per FnOnce<...>
, ma solo la sintassi zuccherata sarà stabilizzata per l'interazione con questi tratti a 1,0.)
Poi, la sintassi paren ha una piccola regola in più: inserisce automaticamente vite che agiscono come for<'a>
(in particolare, viene sottoposto a lifetime elision con una durata inserita inserita in un valore for
sul tratto), quindi solo F: FnOnce(&mut Builder)
equivale a F: for<'a> FnOnce(&'a mut Builder)
ed è la versione consigliata.
L'applicazione di queste correzioni al tuo esempio box:
pub fn initialize_with_closure<F>(rules: F) -> uint where F: FnOnce(&mut uint) {
let mut i = 0;
rules(&mut i);
i
}
// equivalently
pub fn initialize_with_closure_explicit<F>(rules: F) -> uint where F: for<'a> FnOnce(&'a mut uint) ->() {
let mut i = 0;
rules(&mut i);
i
}
pub fn main() {
initialize_with_closure(|i: &mut uint| *i = *i + 20);
initialize_with_closure_explicit(|i: &mut uint| *i = *i + 20);
}
playpen
Close-elettore: perché questo è offtopic? – huon