首页 文章

Rust匹配和借用检查器

提问于
浏览
0

我一直磕磕绊绊地看着我的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 函数试图以可变方式借用自己,这已经在match语句之上不可靠地借用以打开读写锁 .

我在Rust中遇到过这种模式几次,主要是在使用 RwLock 时 . 我也找到了一个解决方法,即在 match 语句之前引入一个布尔值,然后在 Some arm中更改boolean的值,然后在match语句之后最后引入一个测试,以执行我想要的任何操作做 Some 手臂 .

在我看来,在Rust中这样做更为惯用的方法 - 或者以完全不同的方式解决问题 - 但我可以't find it. If I'毫无疑问,问题与词汇借用有关,所以 self 不能在内部可变地借用比赛声明的武器 .

是否有一种惯用的Rust方式来解决这类问题?

2 回答

  • 1

    直接使用字段 those ,例如使用自定义类型:

    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 => {}
            }
        }
    }
    
  • 2

    你需要在变异 self 之前结束借用 self 的一部分

    pub fn bar1(&mut self) {
        let foo = self.test.write().unwrap().foo();
        match foo {
            Some(thing) => {
                self.add(thing);
            },
            None => {}
        }
    }
    

    或直接改变 self 的非借入部分

    pub fn bar2(&mut self) {
        let test_writer = self.test.write().unwrap();
    
        match test_writer.foo() {
            Some(thing) => {
                self.those += thing;
            },
            None => {}
        }
    }
    

相关问题