A more elegant way to match after a HashMap value than cloning

I learn Rust using the Rust Programming Language . I am working on the following task in the chapter on closure :

Try changing Cacherto save a hash map, not a single value. The keys of the hash map will be the values argthat are transmitted, and the values ​​of the hash map will be the result of a close call on this key. Instead of looking to see if or has a self.valuevalue , the value function will search the hash map and return the value if it is present. If it is absent, it will cause a closure and save the resulting value in the hash map associated with its value .SomeNoneargCacherarg

This is my decision:

use std::collections::HashMap;

struct Cacher<T>
where
    T: Fn(i32) -> i32,
{
    calculation: T,
    values: HashMap<i32, i32>,
}

impl<T> Cacher<T>
where
    T: Fn(i32) -> i32,
{
    fn new(calculation: T) -> Cacher<T> {
        Cacher {
            calculation,
            values: HashMap::new(),
        }
    }
    fn value(&mut self, arg: i32) -> i32 {
        match self.values.get(&arg) {
            Some(v) => *v,
            None => {
                let v = (self.calculation)(arg);
                self.values.insert(arg, v);
                v
            }
        }
    }
}

:

error[E0502]: cannot borrow `self.values` as mutable because it is also borrowed as immutable
  --> src/main.rs:26:17
   |
22 |         match self.values.get(&arg) {
   |               ----------- immutable borrow occurs here
...
26 |                 self.values.insert(arg, v);
   |                 ^^^^^^^^^^^ mutable borrow occurs here
...
29 |         }
   |         - immutable borrow ends here

, :

match self.values.clone().get(&arg) { ...

HashMap, match ?

+4

Source: https://habr.com/ru/post/1684524/


All Articles