In the Closures chapter of the second edition of The Rust Programming Language, the writer implements a Cache
struct and leaves it with a few problems for the reader to fix up, such as:
- Accepting generic parameters and return values on the closure function
- Allowing more than one value to be cached
I've attempted to fix those problems but I am quite stuck and can't make it work.
use std::collections::HashMap;
use std::hash::Hash;
struct Cacher<T, X, Y>
where
T: Fn(&X) -> &Y,
X: Eq + Hash,
{
calculation: T,
results: HashMap<X, Y>,
}
impl<T, X, Y> Cacher<T, X, Y>
where
T: Fn(&X) -> &Y,
X: Eq + Hash,
{
fn new(calculation: T) -> Cacher<T, X, Y> {
Cacher {
calculation,
results: HashMap::new(),
}
}
fn value<'a>(&'a mut self, arg: &'a X) -> &'a Y {
match self.results.get(arg) {
Some(v) => v,
None => {
let res = (self.calculation)(arg);
self.results.insert(*arg, res);
res
}
}
}
}
Where T
is the closure function type, X
is the argument type and Y
is the return value type.
The error I get:
error[E0308]: mismatched types
--> src/main.rs:30:43
|
30 | self.results.insert(*arg, res);
| ^^^ expected type parameter, found &Y
|
= note: expected type `Y`
found type `&Y`
I understand this, but I can't think of an elegant solution for the whole ordeal.