简体   繁体   中英

Using RwLock.read() on a mutable struct

I'm trying to use a RwLock around a mutable struct, but I can't make it compile and I'm not sure why.

Here's a minimum code sample:

use std::sync::RwLock;
use lru::LruCache;

fn main() {
        let mut cache: LruCache<String,String> = LruCache::new(100);
        cache.put("test".to_string(), "test_value".to_string());
        let lock_cache = RwLock::new(cache);
        let rc = lock_cache.read();
        let res = rc.unwrap().get("test");
        assert_eq!(res.unwrap().as_str(), "test_value");
}

where LruCache comes from an external Rust crate (but I don't think it has a specific role in the issue). The compiler complains with this message:

error[E0596]: cannot borrow data in a dereference of `RwLockReadGuard<'_, LruCache<String, String>>` as mutable
   --> tests/cache_test.rs:295:15
    |
295 |     let res = rc.unwrap().get("test");
    |               ^^^^^^^^^^^ cannot borrow as mutable
    |
    = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `RwLockReadGuard<'_, LruCache<String, String>>`

I checked the docs for RwLock and while RwLockWriteGuard does implement DerefMut , RwLockReadGuard does not.

I'm quite new to Rust so I'm pretty sure I'm doing something wrong. Is there a way I can workaround the DerefMut is required but not implemented, compiler error?

EDIT I changed the code so that is easily executable from a main file.

LruCache::get requires &mut self , as per its signature ( docs ):

pub fn get<'a, Q>(&'a mut self, k: &Q) -> Option<&'a V> 

This is because of the nature of LRU caches: in order to keep track which items were most recently used, the cache needs to modify (write) its state:

<...> Moves the key to the head of the LRU list if it exists.

even though you're doing a "read" operation.

So, in your case, RwLock wins you nothing over Mutex , as you have to acquire a write lock anyway. The simplest options are either to use a Mutex<LruCache<K, V>> instead, or choose another way of caching.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM