Próbuję zbudować rozwiązanie do Graham´s accumulator factory challenge, które zasadniczo wymaga funkcji zwrócenia zamknięcia, które zamyka zmienną zmienną numeryczną, której wartość początkowa jest odbierana przez parametr. Każde wywołanie tego zamknięcia zwiększa tę przechwyconą zmienną o wartość, która jest parametrem zamknięcia i zwraca skumulowaną wartość.Zwracanie zamknięcia z zmiennym środowiskiem
Po przeczytaniu closures RFC i kilku pytaniach dotyczących zwrotu zamkniętych zamknięć (w szczególności this). W końcu mogłem wymyślić rozwiązanie, które się kompiluje, ale wynik nie jest tym, czego bym się spodziewał.
#![feature(unboxed_closures, unboxed_closure_sugar)]
fn accumulator_factory(n: f64) -> Box<|&mut: f64| -> f64> {
let mut acc = n;
box |&mut: i: f64| {
acc += i;
acc
}
}
fn main() {
let mut acc_cl = accumulator_factory(5f64);
println!("{}", acc_cl.call_mut((3f64,)));
println!("{}", acc_cl.call_mut((3f64,)));
}
AFAIK to zamknięcie przechwytuje acc
przez wartość, wygenerowany struct, który działa jako środowisko jest zmienny i acc_cl
powinny zachować tę samą instancję środowiska między rozmowami.
W obu przypadkach wynik drukowania jest 6
, więc wygląda na to, że zmodyfikowana wartość nie występuje. I co bardziej mylące jest to, jak obliczany jest ten wynik. Przy każdym wykonaniu zamknięcia początkowa wartość acc
to 3
, mimo że n
jest 5
, gdy zostanie wywołana.
Jeśli zmodyfikować generator do tego:
fn accumulator_factory(n: f64) -> Box<|&mut: f64| -> f64> {
println!("n {}", n);
let mut acc = n;
box |&mut: i: f64| {
acc += i;
acc
}
}
następnie wykonywanie zawsze powrócić 3
i wartość początkowa acc
zawsze 0
w pozycji zamknięcia.
Ta różnica w semantyce wygląda jak błąd. Ale poza tym, dlaczego środowisko jest resetowane między połączeniami?
To zostało wykonane z rustc 0.12.0.
dla innego podejścia możesz sprawdzić to rozwiązanie: https://github.com/Hoverbear/rust-rosetta/blob/master/src/accumulator_factory.rs. Nowe zamknięte w rudzie zamknięcia w rdzeniu to cukier na strukturę i implementacja cechy. Ta wersja pisze długą "nieusuwalną" wersję. –