Dies bedeutet, dass es unmöglich ist, wandelbar Methoden zu verwenden, auf irgendeiner der Methoden des Iterators (find
, filter
, etc.)?
In den Methoden, die einen Parameter vom Typ F: Fn*(&Self::Item)
erhalten, ja. Man kann keine Methode aufrufen, die eine veränderbare Referenz (&mut
) auf eine Referenz (&
) erwartet. Zum Beispiel:
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
Beachten Sie, dass diese Regel auch für die automatische Deref gilt.
Einige Methoden der Iterator
erhalten einen Parameter vom Typ F: Fn*(Self::Item)
, wie map
, filter_map
usw. Diese Methoden Funktionen ermöglichen, die das Element mutieren.
Eine interessante Frage ist: Warum haben manche Methoden erwarten Fn*(&Self::Item)
und andere Fn*(Self::item)
?
Die Methoden, die das Element, wie filter
(das wird das Einzelteil, wenn die Filter-Funktion gibt true
) verwenden müssen, nicht Self::Item
als Parameter an die Funktion übergeben kann, da dadurch, dass das Eigentum an dem Punkt bedeutet geben die Funktion. Aus diesem Grund übergeben Methoden wie filter
&Self::Item
, so dass sie das Element später verwenden können.
Auf der anderen Seite, Methoden wie map
und filter_map
brauchen das Element nicht, nachdem sie als Argument verwendet werden (die Elemente, nachdem all abgebildet werden), so dass sie passieren das Element als Self::Item
.
Im Allgemeinen ist es möglich, filter_map
zu verwenden, um die Verwendung von filter
in Fällen zu ersetzen, dass die Elemente mutiert werden müssen. In Ihrem Fall, können Sie dies tun:
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());
}
}
Die filter_map
filtert None
Werte und erzeugt die Werte eingewickelt in Some
s.
Danke für die tolle Antwort. Eine andere Option, die in einigen Situationen funktionieren könnte, ist iter_mut(), aber libusb implementiert sie leider nicht. –
Im Allgemeinen erzeugt 'iter_mut'' Item = & mut T', also '& Item = && mut T'. Das bedeutet, dass die Filterfunktion das Element nicht mutieren kann ... Siehe https://play.rust-lang.org/?gist=f01e4c90f80a777c10f01e217e29f739&version=stable&backtrace=0 – malbarbo