我一直在我的 Rust 程序中遇到一种模式,这种模式总是让我与借用检查器发生冲突。考虑以下玩具示例:
use std::sync::{Arc,RwLock};
pub struct Test {
thing: i32,
}
pub struct Test2 {
pub test: Arc<RwLock<Test>>,
pub those: i32,
}
impl Test {
pub fn foo(&self) -> Option<i32> {
Some(3)
}
}
impl Test2 {
pub fn bar(&mut self) {
let mut test_writer = self.test.write().unwrap();
match test_writer.foo() {
Some(thing) => {
self.add(thing);
},
None => {}
}
}
pub fn add(&mut self, addme: i32) {
self.those += addme;
}
}
这不会编译,因为 Some
arm 中的 add
函数试图可变地借用 self,它已经在 match 语句上方被不变地借用以打开读写锁。
我在 Rust 中遇到过几次这种模式,主要是在使用 RwLock
时。我还找到了一个解决方法,即在 match
语句之前引入一个 bool 值,然后更改 Some
臂中的 bool 值,最后引入一个测试match 语句之后的这个 bool 值,用于执行我想在 Some
arm 中执行的任何操作。
在我看来,这不是解决问题的方法,我认为在 Rust 中有更惯用的方法来做到这一点——或者以完全不同的方式解决问题——但我找不到它。如果我没记错的话,这个问题与词法借用有关,所以 self
不能在 match 语句的范围内可变地借用。
是否有惯用的 Rust 方法来解决这类问题?
最佳答案
直接使用字段那些
,例如自定义类型:
use std::sync::{Arc,RwLock};
pub struct Those(i32);
impl Those {
fn get(&self) -> i32 {
self.0
}
fn add(&mut self, n: i32) {
self.0 += n;
}
}
pub struct Test {
thing: Those,
}
pub struct Test2 {
pub test: Arc<RwLock<Test>>,
pub those: Those,
}
impl Test {
pub fn foo(&self) -> Option<Those> {
Some(Those(3))
}
}
impl Test2 {
pub fn bar(&mut self) {
let mut test_writer = self.test.write().unwrap();
match test_writer.foo() {
Some(thing) => {
// call a method add directly on your type to get around the borrow checker
self.those.add(thing.get());
},
None => {}
}
}
}
关于Rust 匹配和借用检查器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45505607/