2016-06-28 2 views
3

나는 inotify 이벤트와 해시 맵에 대한 구조 정보를 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); 

내가 가장 좋은 방법은 watch_service와 Notificator 구조에 어떻게 든 inotify를 변수를 분리하는 것이라고 생각 오류를 받고 있어요,하지만 난 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이 필요하지만이를 해결하는 방법을 알지 못합니다.

+0

'self' 이벤트 실행에서? 그렇지 않은 경우 매개 변수로 사용하지 않으면 문제가 해결 될 수 있습니다. – Noctua

+0

@Noctua, 나는 글쓰기를 잊어 버렸지 만 네, 저는 이벤트 실행에 자신을 사용하고 있습니다. – m0drzew

답변

4

차용 검사기 (more discussion on internals)에 known issue입니다. &T이 범위를 벗어날 때까지 개체에 &mut T을 가져오고 &T을 반환하는 기능을 개체에 다시 액세스 할 수있는 기능을 잃지 않고 반환 할 수는 없습니다. inotify이 구현 된 방식 때문에이 문제를 해결할 수 없습니다.

그러나 can ask the inotify authors을 사용하면 새 데이터를 가져 오지 않는 get_available_notifications 메서드를 만들 수 있습니다. 이 방법을 사용하면 available_notifications으로 한 번 호출하여 반환 값을 삭제할 수 있습니다. 그런 다음 get_available_notifications (&mutINotify이 아니라 단지 &INotify)으로 전화하여 거기에서 일하십시오.

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) 
} 

을 ve는 playground에 작은 개념 증명을 만들었습니다 (vecs는 u64을 가변 상태로 사용하지만 원리는 비슷합니다). 어떤 외부 클라이언트가 Notifier을 빌려 (변경 가능하게) 빌려주고, 빌려주고, 빌려 (불확실하게) 빌려서 (처리 할 수 ​​있도록) 코드를 리팩토링하는 것이 더 클 수도 있습니다 ...

+0

깔끔한 해결 방법 –

+0

참으로 깔끔한 해결 방법입니다. –

+0

좋아요, 코드를 다시 써 보려고했는데 이제'check_for_events' 함수의 두 번째 줄에''self ''가 충분히 길지 않습니다. – m0drzew