我有一个这样的场景:Rust Playground
Container带锁的结构,可以保护多个成员。我不希望每个成员都有 RwLock。complex_mutation来执行一些复杂的逻辑并改变这个结构。_guard锁保护获取一个引用,然后调用另一个函数complex_mutation,其中&mut self传递的结果会导致多个不可变 + 可变引用。complex_mutation那么这一切都会起作用,但这对于现实世界的场景来说太丑陋了。这是 C++ 中的常见模式。我如何在 RUST 中解决这个问题?
你似乎对一些事情感到困惑。让我试着澄清一下。
(),这是毫无意义的。&mut self,那么锁对你没有帮助。&mut锁是允许您从共享引用 ( )获取独占引用 ( ) 的众多机制之一&。当您从共享引用开始时写入值的能力称为“内部可变性”,它是由RwLock、Mutex、RefCell等实现的。如果您已经从独占引用开始,则内部可变性是多余的。有了这个,您要做的就是将您类型中的数据放入锁中。您可以使用元组来完成此操作,但更好的主意是私有“内部”类型,如下所示:
struct Container {
lock: RwLock<ContainerInner>,
}
struct ContainerInner {
pub data1: u32,
pub data2: u32,
}
Run Code Online (Sandbox Code Playgroud)
现在,你想取而代之&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;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果你有一个&mut selfthen 你实际上并不需要锁定;允许您在没有锁定的RwLock::get_mut()情况下获得锁的&mut内部值,因为拥有锁是该值不被共享的静态保证。&mut&mut
如果它在概念上对您有帮助,&并且工作方式&mut类似于和分别 - 您可以有多个或单个,如果您有 a 则不能有 a 。(这有点简化,但您明白了。)与运行时锁不同,Rust 编译器会在编译时检查这些锁是否正确使用,这意味着不需要运行时检查或锁。RwLockread()write()&&mut&mut&
所以你可以添加这样的方法:
impl Container {
pub fn update_date_mut(&mut self, val1: u32, val2: u32) {
self.lock.get_mut().unwrap().complex_mutation(val1, val2);
}
}
Run Code Online (Sandbox Code Playgroud)
这与其他方法完全相同,除了我们采用的方法&mut self允许我们使用get_mut()代替write(),绕过锁。编译器不会让您调用此方法,除非它可以证明该值不是共享的,因此如果编译器允许您使用它,则可以安全地使用它。否则,您需要使用其他方法,该方法将锁定。
| 归档时间: |
|
| 查看次数: |
116 次 |
| 最近记录: |