Borrowing issues with attempted caching

后端 未结 2 1811
南旧
南旧 2021-01-12 02:23

The following code snippet does the same things in 3 ways.

use std::collections::HashMap;

struct Foo {
    cache: HashMap,
}

impl Foo         


        
相关标签:
2条回答
  • 2021-01-12 02:57

    Rust doesn't handle this sort of caching well at the moment.

    The best solution is to avoid the problem altogether. Does show_impl really need to be a method of Foo? If not, you can define a new trait and implement it for String. For example:

    trait ShowImpl: std::fmt::Display {
        fn show_impl(&self) {
            println!("{}", self);
        }
    }
    
    impl ShowImpl for String {}
    

    Then just call show_impl on the string: self.get_cached(key).show_impl();


    Here is a solution that uses UnsafeCell. I'm not sure if it works correctly. While it does compile, the use of unsafe code means the compiler can no longer guarantee safety.

    use std::collections::HashMap;
    use std::cell::UnsafeCell;
    
    struct Foo {
        cache: UnsafeCell<HashMap<String, String>>,
    }
    
    impl Foo {
        fn get_cached(&self, key: &String) -> &String {
            unsafe {
                if !(*self.cache.get()).contains_key(key) {
                    (*self.cache.get()).insert(key.clone(), String::from("default"));
                }
                (*self.cache.get()).get(key).unwrap()
            }
        }
        fn show_impl(&self, what: &String) {
            println!("{}", what);
        }
        pub fn show1(&mut self, key: &String) {
            println!("{}", self.get_cached(key));
        }
        pub fn show2(&mut self, key: &String) {
            unsafe {
                if !(*self.cache.get()).contains_key(key) {
                    (*self.cache.get()).insert(key.clone(), String::from("default"));
                }
                self.show_impl((*self.cache.get()).get(key).unwrap());
            }
        }
    
        pub fn show3(&self, key: &String) {
            self.show_impl(self.get_cached(key));
        }
    }
    
    fn main() {}
    
    0 讨论(0)
  • 2021-01-12 03:06

    You could try to add &mut on self on show_impl as in

    ...
    fn show_impl(&self, what: &String)  
    ...
    

    So it won't get mixed.

    0 讨论(0)
提交回复
热议问题