在可变结构上使用 RwLock.read()

Using RwLock.read() on a mutable struct

我正在尝试围绕一个可变结构使用 RwLock,但我无法编译它,我也不确定为什么。

这是一个最小的代码示例:

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");
}

其中 LruCache 来自外部 Rust crate(但我认为它在问题中没有特定作用)。 编译器抱怨此消息:

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>>`

我检查了 RwLock 的文档,虽然 RwLockWriteGuard 确实实现了 DerefMut,但 RwLockReadGuard 没有。

我对 Rust 很陌生,所以我很确定我做错了什么。有没有办法解决 DerefMut 是必需的但未实现,编译器错误?

编辑 我更改了代码,以便可以从主文件轻松执行。

LruCache::get 需要 &mut self,根据其签名 (docs):

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

这是因为 LRU 缓存的性质:为了跟踪最近使用的项目,缓存需要修改(写入)其状态:

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

即使您正在进行“读取”操作。

因此,在您的情况下,RwLockMutex 更胜一筹,因为您无论如何都必须获得写锁。最简单的选择是使用 Mutex<LruCache<K, V>> 代替,或者选择另一种缓存方式。