0

我正在尝试在可变结构周围使用 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");
}

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

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确实实现了DerefMutRwLockReadGuard但没有。

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

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

4

1 回答 1

1

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

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

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

<...> 如果存在,则将键移动到 LRU 列表的头部。

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

所以,在你的情况下,RwLock你什么也得不到Mutex,因为无论如何你都必须获得一个写锁。最简单的选项是使用 aMutex<LruCache<K, V>>代替,或者选择另一种缓存方式。

于 2021-10-18T17:07:12.907 回答