我正在尝试在Rust中实现键值存储的抽象。因此,我有两个特征:IStorageSystem
,它被分成多个IStore
,提供实际的键值对。如果打开商店,则应锁定内部树形图,直到打开的商店超出范围。此外,整个访问应该是线程安全的:
use std::collections::BTreeMap;
use std::sync::{Arc, RwLock, RwLockReadGuard};
pub type Bytes = Vec<u8>;
pub trait IStorageSystem {
fn open_read<'sys>(&'sys mut self, name: &str) -> Box<IReadOnlyStore<'sys> + 'sys>;
}
pub trait IReadOnlyStore<'sys> {
fn get(&'sys self, key: &Bytes) -> Option<&'sys Bytes>;
}
type StoreData = BTreeMap<Bytes, Bytes>;
struct InMemoryStorageSystem {
stores: BTreeMap<String, Arc<RwLock<StoreData>>>,
}
impl InMemoryStorageSystem {
pub fn new() -> InMemoryStorageSystem {
InMemoryStorageSystem {
stores: BTreeMap::new(),
}
}
}
impl IStorageSystem for InMemoryStorageSystem {
fn open_read<'sys>(&'sys mut self, name: &str) -> Box<IReadOnlyStore<'sys> + 'sys> {
let store_data = self.stores.entry(name.into())
.or_insert(Arc::new(RwLock::new(StoreData::new())));
Box::new(ReadOnlyInMemoryStore::new(store_data))
}
}
struct ReadOnlyInMemoryStore<'sys> {
data: RwLockReadGuard<'sys, StoreData>,
}
impl<'sys> ReadOnlyInMemoryStore<'sys> {
fn new(data: &'sys Arc<RwLock<StoreData>>) -> ReadOnlyInMemoryStore<'sys> {
let locked_data = data.read().unwrap();
ReadOnlyInMemoryStore {
data: locked_data,
}
}
}
impl<'sys> IReadOnlyStore<'sys> for ReadOnlyInMemoryStore<'sys> {
fn get(&'sys self, key: &Bytes) -> Option<&'sys Bytes> {
self.data.get(key)
}
}
fn main() {
let mut storage = InMemoryStorageSystem::new();
let store = storage.open_read("values");
let key = String::from("dummy").into_bytes();
let value = store.get(&key);
match value {
Some(ref val) => println!("Got {:?}", value),
None => println!("Nothing found"),
}
}
当我尝试编译此代码时,出现以下错误:
error[E0597]: `*store` does not live long enough
--> src/main.rs:69:1
|
64 | let value = store.get(&key);
| ----- borrow occurs here
...
69 | }
| ^ `*store` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
我该如何解决这个问题?据我所知,这应该有效,因为所有生命周期都绑定到首先创建的存储系统,因此应该最后丢弃。