2016-06-03 2 views
4

내가 이렇게 같은 서명이 libusb::Devices 객체에 Iterator::find을 사용하고 싶습니다 찾을 :: 각 장치. 그러나 device_descriptor 메서드는 각 장치에 &mut이 필요하며 find 메서드는 & 만 제공합니다.변이 항목은

Iterator의 메서드 (find, filter 등) 중 하나에서 변경 가능한 메서드를 사용할 수 없다는 뜻입니까? 이 그것을 변경할 방법을 사용하는 것은 불가능하다는 뜻

error: cannot borrow immutable borrowed content `*dev` as mutable 

답변

5

: 내가지고있어 오류 여기

let mut device = context 
    .devices() 
    .unwrap() 
    .iter() 
    .find(&mut |dev: &libusb::Device| { 
     dev.device_descriptor().unwrap().vendor_id() == vendor_id 
    }) 
    .unwrap(); 

됩니다 : 여기

내가 작업을 얻기 위해 노력하고있어 예입니다 어떤 반복자의 메서드 ( find, filter, 등)?

F: Fn*(&Self::Item) 유형의 매개 변수를받는 방법에서 예. 참조 (&)에서 변경 가능한 참조 (&mut)를 예상하는 메소드를 호출 할 수 없습니다. 예 :

let mut x = vec![10]; 
// (&x)[0] = 20; // not ok 
(&mut x)[0] = 20; // ok 

//(& (&x))[0] = 20; // not ok 
//(& (&mut x))[0] = 20; // not ok 
(&mut (&mut x))[0] = 20; // ok 

이 규칙은 auto deref에도 적용됩니다. Iterator

일부 방법 등 map, filter_map처럼 이러한 방법은 항목을 변이 기능을 허용 입력 F: Fn*(Self::Item)의 매개 변수를받을 수 있습니다.


한 가지 흥미로운 질문 : 왜 어떤 방법 Fn*(&Self::Item)Fn*(Self::item)을 기대합니까?

하고 그에 항목의 소유권을 부여 의미하기 때문에, 함수에 매개 변수로 Self::Item을 전달할 수 없습니다 (필터 기능이 true를 반환하는 경우 그 항목을 반환합니다) filter 같은 항목을 사용해야합니다 방법 함수. 이러한 이유로 filter과 같은 메서드는 &Self::Item을 전달하므로 나중에 해당 항목을 사용할 수 있습니다.

한편, mapfilter_map과 같은 메서드는 항목을 사용한 후 (항목이 결국 매핑 됨) 항목을 필요로하지 않으므로 항목을 Self::Item으로 전달합니다. 일반적으로


, 항목이 돌연변이 될 필요가 있다는 경우에 filter의 사용을 대체 할 filter_map을 사용하는 것이 가능하다. None 값을

extern crate libusb; 

fn main() { 
    let mut context = libusb::Context::new().expect("context creation"); 

    let mut filtered: Vec<_> = context.devices() 
     .expect("devices list") 
     .iter() 
     .filter_map(|mut r| { 
      if let Ok(d) = r.device_descriptor() { 
       if d.vendor_id() == 7531 { 
        return Some(r); 
       } 
      } 
      None 
     }) 
     .collect(); 

    for d in &mut filtered { 
     // same as: for d in filtered.iter_mut() 
     println!("{:?}", d.device_descriptor()); 
    } 
} 

filter_map 필터를하고 Some들에 래핑 된 값을 생성 : 귀하의 경우, 당신은이 작업을 수행 할 수 있습니다.

+0

대단한 답변을 보내 주셔서 감사합니다. 어떤 상황에서는 iter_mut()에서 사용할 수있는 또 다른 옵션이 있지만, 안타깝게도 libusb는이를 구현하지 않습니다. –

+1

일반적으로 iter_mut은'Item = & mut T '를 생성하므로'& Item = && mut T'입니다. 즉, 필터 기능으로 항목을 변경할 수 없습니다. https://play.rust-lang.org/?gist=f01e4c90f80a777c10f01e217e29f739&version=stable&backtrace=0을 참조하십시오. – malbarbo