我正在尝试封装一些代码以避免重复它,这些代码涉及从 Mutex 中借用数据以及随后的进一步操作(由于超出范围,我将其从这个问题中删除,但这是激励因素)。
以下示例代码提示 guard
的生命周期不够长。但这正是我在专门为此目的设计的结构中返回 guard
的原因。
这是借用检查器的限制吗?关于解决此问题的任何建议?
use std::sync::{Mutex,MutexGuard};
use std::ops::DerefMut;
pub struct InnerData {
count: i32 // sample only
}
pub struct Data {
pub inner_data: Mutex<InnerData>
}
pub struct BorrowedInnerData<'a> {
pub inner_data: &'a mut InnerData,
guard: MutexGuard<'a,InnerData>,
}
impl Data {
pub fn borrow_inner_data<'a>(&'a mut self) -> BorrowedInnerData<'a> {
let guard = self.inner_data.lock().unwrap();
BorrowedInnerData {
inner_data: guard.deref_mut(),
guard: guard,
}
}
}
fn main() {
let mut data = Data {
inner_data: Mutex::new( InnerData {
count: 5
}),
};
let borrowed_inner_data = data.borrow_inner_data();
}
最佳答案
让我们看看 DerefMut
trait :
pub trait DerefMut: Deref {
fn deref_mut(&'a mut self) -> &'a mut Self::Target;
}
这意味着当deref_mut
被调用时,将返回一个引用,该引用与被取消引用的值一样长。但是,您正在移动 guard
当你把它移到 BorrowedInnerData
.这意味着该值停止存在于一个内存位置并从一个新位置开始。作为Veedrac hints at ,完全有可能通过移动守卫,使引用无效。这会很糟糕并导致崩溃(在最好的情况下)。
但是,没有真正的理由保留 guard
和 inner_data
.因为Deref
和 DerefMut
, 一个 MutexGuard<InnerData>
可以像&InnerData
一样使用或 &mut InnerData
.只需删除 inner_data
从你的结构中保留 guard
.
关于rust - 从 Mutex 中同时借用引用和保护,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32194269/