你似乎对几件事感到困惑.让我试着澄清一下.
- 铁 rust 中的锁保护锁中包含的数据.在这种情况下,您是在保护
()
,这是没有意义的.
- 如果你拿的是
&mut self
,那么锁对你没有帮助.锁是允许您从共享引用(&
)获得独占引用(&mut
)的众多机制之一.从共享引用开始写入值的能力称为"内部可变性",它由RwLock
实现,也由Mutex
、RefCell
等实现.如果你已经从独占引用开始,内部可变性是多余的.
这样一来,您要做的就是将类型中的数据放入锁中.您可以使用元组来实现这一点,但更好的方法是使用私有的"内部"类型,如下所示:
struct Container {
lock: RwLock<ContainerInner>,
}
struct ContainerInner {
pub data1: u32,
pub data2: u32,
}
现在,你想拿&self
英镑来代替.
如果您有需要对ContainerInner
中的数据进行操作的方法,因为您从多个位置调用它们,则可以简单地将它们放在ContainerInner
中,如下所示:
impl Container {
pub fn update_date(&self, val1: u32, val2: u32) {
self.lock.write().unwrap().complex_mutation(val1, val2);
}
}
impl ContainerInner {
fn complex_mutation(&mut self, val1: u32, val2: u32) {
self.data1 = val1;
self.data2 = val2;
}
}
请注意,如果您有&mut self
,那么您实际上不需要锁定;如果您有&mut
到锁without locking,则RwLock::get_mut()
允许您获得内部值的&mut
,因为锁有&mut
是静态的,即该值不是共享的.
如果它在概念上对你有帮助,&
和&mut
的工作原理分别类似于RwLock
的S read()
和write()
--你可以有多个&
,也可以有一个&mut
,如果你有&mut
,你就不能有&
.与运行时锁不同,Rust编译器会在编译时判断这些锁是否被正确使用,这意味着不需要运行时判断或锁.
因此,您可以添加如下所示的方法:
impl Container {
pub fn update_date_mut(&mut self, val1: u32, val2: u32) {
self.lock.get_mut().unwrap().complex_mutation(val1, val2);
}
}
这与其他方法完全相同,不同之处在于我们使用&mut self
,它允许我们使用get_mut()
代替write()
,从而绕过锁.编译器不会让您调用此方法,除非它能证明该值不是共享值,因此,如果编译器允许您使用它,则可以安全地使用它.否则,您需要使用另一种方法,该方法将锁定.