Being an aspiring rustacean, I've been working my way through The Rust Programming Language book and being in the 13th chapter I was attempting to generalize the Cacher struct, that has as a purpose implementing lazy evaluation around a closure. While I was able to use generics to generalize the closure signature to any one parameter with any one output type, I can't figure out how to generalize this to closures with any number of params. I feel like there should be a way to do this.
struct Cacher<'a, Args, V: Clone>
{
calculation: &'a dyn Fn(Args) -> V,
value: Option<V>
}
impl<'a, Args, V: Clone> Cacher<'a, Args, V>
{
fn new(calculation: &'a dyn Fn(Args) -> V) -> Cacher<Args, V> {
Cacher {
calculation: calculation,
value: None,
}
}
fn value(&mut self, arg: Args) -> V {
// all this cloning is probably not the best way to do this
match self.value.clone() {
Some(v) => v,
None => {
let v = (self.calculation)(arg);
self.value = Some(v.clone());
v
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let mut cached_func = Cacher::new(&(|asd| asd + 1));
assert_eq!(cached_func.value(1), 2);
assert_eq!(cached_func.value(4), 2);
}
#[test]
fn it_works_too() {
// compiler hates this
let mut cached_func = Cacher::new(&(|asd, qwe| asd + qwe));
assert_eq!(cached_func.value(1, 1), 2);
assert_eq!(cached_func.value(4, 1), 2);
}
}