Passing Verschlüsse in Rust ist recht unkompliziert, aber bei der Speicherung von Verschlüssen für die Wiederverwendung gibt es mehrere Lösungen (verwenden Sie generische Funktionsarten, Referenzverschlüsse oder Box, Box mit 'static
Lebensdauer oder nicht? ...).Idiomatische Art, einen Verschluss zur Wiederverwendung aufzubewahren?
Während ich durch diese mehrere Male mit verschiedenen Arten von Boxed-Typen verwirrt habe, lesen Sie über ähnliche Q & A's und könnte sogar eine Vermutung bei der Beantwortung dieser Frage riskieren. Ich habe kein Gefühl dafür, wie ich damit umgehen soll, selbst für den einfachen/offensichtlichen Fall, oder was für ein guter Ausgangspunkt wäre.
Um die Frage konkreter zu machen, was wäre ein guter Weg, um dieses Beispiel speichern Funktionen zur Wiederverwendung, mit dem Builder-Muster zu speichern Schließungen später aufgerufen werden.
// This example looks a bit long but its really very simple.
// * This example is most of the way to implementing the builder pattern,
// it ust runs the code immediately instead of storing input
// to run on `build()`.
// * Changes should only be needed where the comment `stored closures:`
// has been written.
// * I've attempted to make this example as generic as possible,
// but not _so_ simple that the answer wont apply to real-world use (hopefully!).
struct MyActions {
num: i32,
times: i32,
// stored closures: should be stored here.
// update_fn: Option<Fn(...)>,
// twiddle_fn: Option<Fn(...)>,
}
impl MyActions {
pub fn new(num: i32) -> Self {
return MyActions {
num: num,
times: 1,
}
}
pub fn build(self) -> i32 {
// stored closures:
// should run both actions if they're defined and return the result.
return self.num;
}
pub fn num_times(mut self, times: i32) -> Self {
self.times = times;
self
}
pub fn num_update<F>(mut self, func: F) -> Self
where
F: Fn(i32) -> i32
{
// stored closures: run immediately for now
for _ in 0..self.times {
self.num = func(self.num);
}
self
}
pub fn num_twiddle<F>(mut self, func: F) -> Self
where
F: Fn(i32) -> i32
{
// stored closures: run immediately for now
for _ in 0..self.times {
self.num = func(self.num);
}
self
}
}
// no changes needed here
fn main() {
let act = MyActions::new(133);
let num_other: i32 = 4;
// builder pattern (currently executes immediately).
let result = act
.num_times(8)
.num_update(|x| x * 2 + num_other)
.num_twiddle(|x| (((x/2) - 1)^(x + 1))^num_other)
.build();
// Lets say we would want this example to work,
// where 'times' is set after defining both functions.
/*
let result = act
.num_update(|x| x * 2 + num_other)
.num_twiddle(|x| (((x/2) - 1)^(x + 1))^num_other)
.num_times(8) // <-- order changed here
.build();
*/
println!("done: {}", result);
}