在结构中借用参考

时间:2016-06-28 14:25:47

标签: rust

我正在尝试将一个关于inotify事件和hashmap的结构信息与inotify watch id作为键和文件名作为值。

extern crate inotify;
use inotify::INotify;
use std::sync::{Arc, Mutex};
use std::collections::HashMap;

struct Notificator {
    inotify: INotify,
    watch_service: Arc<Mutex<HashMap<inotify::wrapper::Watch, Arc<String>>>>,
}

impl Notificator {
    pub fn new() -> Notificator {
        Notificator {
            inotify: INotify::init().unwrap(),
            watch_service: Arc::new(Mutex::new(HashMap::new())),
        }
    }

    pub fn resolving_events(&mut self) {
        {
            let mut events = self.check_for_events();
            self.events_execution(events);
        }

    }

    fn check_for_events(&mut self) -> &[inotify::wrapper::Event] {
        self.inotify.available_events().unwrap()
    }

    fn events_execution(&self, events: &[inotify::wrapper::Event]) {
        for event in events.iter() {

        }
    }
}

在编译期间,我收到错误

src/main.rs:204:13: 204:17 error: cannot borrow `*self` as immutable because it is also borrowed as mutable [E0502]
src/main.rs:204             self.events_execution(events);

我认为最好的解决方案是将Notificator结构中的inotify变量与watch_service分开,但我不能解除引用self.check_for_events();因为我收到了

src/main.rs:203:17: 203:27 error: the trait bound `[inotify::wrapper::Event]: std::marker::Sized` is not satisfied [E0277]
src/main.rs:203             let mut events = *self.check_for_events();

我理解问题的核心:我试图借check_for_events借用参考,然后将其用作events_execution中的参数,这也需要self作为参数,但我有不知道如何解决它。

2 个答案:

答案 0 :(得分:6)

然后可以使用:

pub fn resolving_events(&mut self) {
    let (slf, events) = self.check_for_events();
    slf.events_execution(events);

}

fn check_for_events(&mut self) -> (&Self, &[inotify::wrapper::Event]) {
    let events = self.inotify.available_events().unwrap();
    (&self, events)
}

我在playground上做了一个小概念验证(使用u64的vecs作为可变状态,但原理类似)。重构代码可能更清晰,以便某些外部客户端可以(可变地)借用Notifier,生成事件,释放借用,并借用它(不可变)来处理它们......

答案 1 :(得分:4)

这是借阅检查器中的known issuemore discussion on internals)。在&mut T超出范围之前,您无法将&T函数带到对象并返回&T而不会失去再次访问该对象的能力。由于inotify的实施方式,您无法解决这个问题。

但是您can ask the inotify authors要创建一个不会获取新数据的get_available_notifications方法。这样,您可以调用available_notifications一次并删除返回的值。然后拨打get_available_notifications(不会&mutINotify,只需&INotify)并从那里开始工作。