Btw, correct me if I'm wrong in saying "A mutable borrow inside immutable borrow".
I have this code.
use std::collections::HashMap;
#[cfg(test)]
mod test {
use super::Cacher;
#[test]
fn normal_usage() {
use std::thread;
use std::time::Duration;
let mut cached_caller = Cacher::new (| arg : &str | {
println!("calculating slowly...");
thread::sleep(Duration::from_secs(2));
String::from(arg).len()
});
assert_eq!(cached_caller.value("32"), 2);
assert_eq!(cached_caller.value("agath"), 5);
assert_eq!(cached_caller.value("32"), 2);
assert_eq!(cached_caller.value("agath"), 5);
}
}
pub struct Cacher<T, G, H>
where H: Clone, T: Fn(G) -> H,
{
mapping: HashMap<G, H>,
calculation: T,
}
impl<T, G, H> Cacher<T, G, H>
where H: Clone, T: Fn(G) -> H, G: std::cmp::Eq, G: std::hash::Hash, G: Clone {
pub fn new(calculation: T) -> Cacher<T, G, H> {
Cacher {
mapping: HashMap::new(),
calculation: calculation,
}
}
pub fn value(&mut self, arg: G) -> H {
let res = match self.mapping.get(&arg) {
Some(v) => Some(v.clone()),
None => None,
};
match res {
Some(v) => v,
None => {
let arg_clone = arg.clone();
let v = (self.calculation)(arg);
let clone = v.clone();
self.mapping.insert(arg_clone, clone);
v
}
}
}
}
Can I not do something like this directly?
pub fn value(&mut self, arg: G) -> H {
// let res = match self.mapping.get(&arg) {
// Some(v) => Some(v.clone()),
// None => None,
// };
match self.mapping.get(&arg) {
Some(v) => v.clone(),
None => {
let arg_clone = arg.clone();
let v = (self.calculation)(arg);
let clone = v.clone();
self.mapping.insert(arg_clone, clone);
v
}
}
}
This gives the error:
Compiling closures v0.1.0 (file:///home/harshithg/dev/rust/closures)
error[E0502]: cannot borrow `self.mapping` as mutable because it is also borrowed as immutable
--> src/lib.rs:53:17
|
47 | match self.mapping.get(&arg) {
| ------------ immutable borrow occurs here
...
53 | self.mapping.insert(arg_clone, clone);
| ^^^^^^^^^^^^ mutable borrow occurs here
...
56 | }
| - immutable borrow ends here
error: aborting due to previous error
error: Could not compile `closures`.
Thank you