我正在编写一个交易数据库。 Transaction
结构包含对需要生命周期注释的 MutexGuard
的引用,因此我必须在事务结构上放置生命周期注释。该事务还具有对环境结构的引用计数:
struct Transaction<'a> {
mutex_guard: MutexGuard<'a, i32>,
env: Arc<Env> //I don't know which lifetime annotation to use here for Env.
}
我希望环境对写入事务有弱引用:
struct Env<'a> {
w_txn: Weak<Transaction<'a>>
}
我必须在 Env
结构上放置生命周期注释,这意味着环境不能比 w_txn
长寿,但这不是我想要的。我希望环境总是比交易存活得更久,这就是我使用 Weak
的原因。
那我该怎么办呢?
一个最小的可重现示例:
use std::sync::{Arc, Mutex, MutexGuard, Weak};
#[derive(Debug)]
struct Env<'a> {
w_txn: Option<Weak<Txn<'a>>>,
}
#[derive(Debug)]
struct Txn<'a> {
env: Arc<Env<'a>>,
mutex_guard: MutexGuard<'a, i32>,
}
impl Txn<'_> {
fn new(env: Arc<Env>, mutex: &Mutex<i32>) -> Arc<Self> {
Arc::new(Self {
env: env.clone(),
mutex_guard: mutex.lock().unwrap(),
})
}
}
fn main() {
let mut env = Arc::new(Env { w_txn: None });
let mut mutex = Mutex::new(0);
let mut txn = Txn::new(env, &mutex);
env.w_txn = Some(Arc::downgrade(&txn));
println!("env: {:?}", env);
println!("txn: {:?}", txn);
}
最佳答案
这似乎解决了生命周期问题:
use std::sync::{Arc, Mutex, MutexGuard, Weak};
#[derive(Debug)]
struct Env<'a> {
w_txn: Option<Weak<Txn<'a>>>,
}
#[derive(Debug)]
struct Txn<'a> {
env: Arc<Env<'a>>,
mutex_guard: MutexGuard<'a, i32>,
}
impl<'a> Txn<'a> {
fn new(env: Arc<Env<'a>>, mutex: &'a Mutex<i32>) -> Arc<Self> {
Arc::new(Self {
env: env.clone(),
mutex_guard: mutex.lock().unwrap(),
})
}
}
fn main() {
let mut env = Arc::new(Env { w_txn: None });
let mut mutex = Mutex::new(0);
let mut txn = Txn::new(env, &mutex);
env.w_txn = Some(Arc::downgrade(&txn));
println!("env: {:?}", env);
println!("txn: {:?}", txn);
}
但是由于各种其他原因,它仍然无法编译。老实说,代码看起来需要重新设计。您尝试做的事情不能很好地与 Rust 一起工作,根据我的经验,这是一个相当大的危险信号,表明总体设计不是一个好的设计。
https://stackoverflow.com/questions/70421933/