Vorrei rimuovere elementi da un BTreeMap
trovati tramite un'iterazione.Rimozione di elementi da BTreeMap rilevati tramite iterazione
Poiché non è possibile rimuovere elementi durante l'iterazione per ovvi motivi, ho messo gli elementi da eliminare in un vettore. Il problema principale è che non è possibile utilizzare un vettore di riferimenti, ma solo un vettore di valori. Tutte le chiavi per le quali è necessario rimuovere la voce devono quindi essere clonate (presupponendo che la chiave implementa il tratto Clone
).
Ad esempio, questo breve campione non si compila:
#![feature(drain)]
use std::collections::BTreeMap;
pub fn clean() {
let mut map = BTreeMap::<String, i32>::new();
let mut to_delete = Vec::new();
{
for (k, v) in map.iter() {
if *v > 10 {
to_delete.push(k);
}
}
}
for k in to_delete.drain(..) {
map.remove(k);
}
}
genera i seguenti errori quando si compila:
src/lib.rs:21:9: 21:12 error: cannot borrow `map` as mutable because it is also borrowed as immutable [E0502]
src/lib.rs:21 map.remove(k);
^~~
src/lib.rs:20:5: 22:6 note: in this expansion of for loop expansion
src/lib.rs:12:23: 12:26 note: previous borrow of `map` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `map` until the borrow ends
src/lib.rs:12 for (k, v) in map.iter() {
^~~
src/lib.rs:12:9: 16:10 note: in this expansion of for loop expansion
src/lib.rs:24:2: 24:2 note: previous borrow ends here
src/lib.rs:4 pub fn clean() {
...
src/lib.rs:24 }
Modifica to_delete.push(k)
con to_delete.push(k.clone())
rende questo frammento compilato correttamente. Tuttavia, è molto costoso se ogni chiave da eliminare deve essere clonata.
C'è una soluzione migliore?
$ rustc --version
rustc 1.5.0-nightly (65d5c0833 2015-09-29)
Mi auguro che alla fine, 'BTreeMap' potrebbe ottenere un metodo come' scarico fn (& auto mut, Gamma) '. Di rilievo è [questo proto RFC] (https://github.com/rust-lang/rfcs/issues/460), ma controlla [questo] (https://github.com/rust-lang/rfcs/ pull/1254) e [questo] (https://github.com/rust-lang/rfcs/pull/1257). –
Shepmaster
@Shepmaster - Ovviamente, la cosa qui è che non è Range, ma piuttosto Range –
LinearZoetrope
@Jsor ah, mi sono perso. Sento che è un caso improbabile, quindi è davvero un caso appiccicoso! – Shepmaster