问题描述
我正在尝试封装一些代码,以避免重复代码,这涉及从Mutex中借用数据并对其进行进一步的操作(我将这个问题排除在范围之外,但这是激励因素).
I'm trying to encapsulate some code to avoid repeating it, relating to borrowing data out of a Mutex and further operations thereupon (which I leave off of this question as out of scope, but are the motivating factors).
以下示例代码抱怨guard
的寿命不足.但这就是为什么我要在专门为此目的设计的结构中返回guard
的原因.
The following sample code complains that guard
does not live long enough. But that is precisely why I'm returning guard
in the structure designed expressly for that purpose.
这是借阅检查器的限制吗?有任何解决此问题的建议吗?
Is this a limitation of the borrow checker? Any suggestions on working around this?
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
特征:
Let's look at the DerefMut
trait:
pub trait DerefMut: Deref {
fn deref_mut(&'a mut self) -> &'a mut Self::Target;
}
这意味着在调用deref_mut
时,将返回一个引用,该引用只要被取消引用的值就有效.但是,将guard
移到BorrowedInnerData
时,您正在移动.这意味着该值停止驻留在一个存储位置,而开始于新的存储位置.正如 Veedrac提示,完全有可能移动警卫,您将使参考无效.这将很糟糕,并导致崩溃(在最佳情况下).
This means that when deref_mut
is called, a reference is returned that lives as long as the value being dereferenced. However, you are moving guard
when you move it to BorrowedInnerData
. This means that the value stops living at one memory location and starts at a new one. As Veedrac hints at, it's entirely possible that by moving the guard, you would invalidate the reference. This would be bad and lead to crashes (in the best case).
但是,没有真正的理由保留guard
和inner_data
.由于Deref
和DerefMut
,可以像&InnerData
或&mut InnerData
一样使用MutexGuard<InnerData>
.只需从结构中删除inner_data
并保留guard
.
However, there's no real reason to keep guard
and inner_data
. Because of Deref
and DerefMut
, a MutexGuard<InnerData>
can be used just like a &InnerData
or &mut InnerData
. Simply remove inner_data
from your struct and keep guard
.
这篇关于从Mutex一起借用参考资料和防护的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!