Ich versuche eine Lösung zu Graham´s accumulator factory challenge aufzubauen, die im Grunde eine Funktion erfordert, um einen Abschluss zurückzugeben, der über eine veränderbare numerische Variable schließt, deren Anfangswert über einen Parameter empfangen wird. Jeder Aufruf dieser Schließung inkrementiert diese erfasste Variable um einen Wert, der ein Parameter für den Abschluss ist, und gibt den akkumulierten Wert zurück.Rückgabe eines Abschlusses mit veränderbarer Umgebung
Nach dem Lesen der closures RFC und einige Fragen über die Rückgabe von ungeöffneten Verschlüssen (insbesondere this). Ich könnte endlich eine Lösung finden, die kompiliert, aber das Ergebnis ist nicht das, was ich erwarten würde.
#![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 dieser Verschluss fängt acc
von Wert, die erzeugte Struktur, die die Umgebung wirkt wie wandelbar ist und acc_cl
sollte die gleiche Umgebung Instanz zwischen den Anrufen halten.
Aber das Druckergebnis ist in beiden Fällen 6
, so scheint es, dass der modifizierte Wert nicht persistiert. Und noch verwirrender ist, wie dieses Ergebnis berechnet wird. Bei jeder Ausführung des Verschlusses ist der Anfangswert acc
3
, obwohl n
5
genannt wird.
Wenn ich ändern den Generator dazu:
fn accumulator_factory(n: f64) -> Box<|&mut: f64| -> f64> {
println!("n {}", n);
let mut acc = n;
box |&mut: i: f64| {
acc += i;
acc
}
}
dann immer die Ausführung zurückkehren 3
und der Anfangswert von acc
ist immer 0
beim Schließen Eintrag.
Dieser Unterschied in der Semantik sieht wie ein Fehler aus. Aber warum wird die Umgebung zwischen den Anrufen zurückgesetzt?
Dies wurde mit Rustc 0.12.0 durchgeführt.
für einen anderen Ansatz können Sie diese Lösung überprüfen: https://github.com/Hoverbear/rust-rosetta/blob/master/src/accumulator_factory.rs. Neue ungeöffnete Verschlüsse im Rost sind Zucker für eine Struktur und eine Trait-Implementierung. Diese Version schreibt die lange "ungezuckerte" Version –