Я хочу переключить направление итератора на основе логического параметра. Я попробовал следующий подход, но он заканчивается ошибкой компиляции:
fn main() {
let numbers = vec![1, 2, 3, 4, 5, 6];
print(&numbers, false);
print(&numbers, true);
}
fn print(what: &[i32], reverse: bool) {
let iter = what.iter();
if reverse {
iter = iter.rev();
}
for n in iter {
println!("{n}");
}
}
Это ошибка, которую я получаю:
// Error:
mismatched types
expected struct `std::slice::Iter<'_, _>`
found struct `Rev<std::slice::Iter<'_, _>>`
Как я могу реализовать желаемое поведение?
Вы можете сделать это с помощью динамической отправки, как описано здесь вот так:
fn iterateMyData(a: &mut VecDeque<A>, b: &mut BTreeMap<u64, VecDeque<B>>) {
// Do something.
let reverse: bool = a.front().unwrap().reverse;
for a_value in a.iter_mut() {
let mut temp_iter1;
let mut temp_iter2;
let mut iter: &mut dyn Iterator<Item = _> = if reverse {
temp_iter1 = b.values_mut().rev();
&mut temp_iter1
} else {
temp_iter2 = b.values_mut();
&mut temp_iter2
};
for b_vec in iter {
// Do something.
}
}
}
и ссылку на rustexplorer.
Однако, как уже отмечалось в связанной ветке выше, вероятно, проще и лучше использовать перечисление (ящик), например , либо вот так
let mut iter =
if reverse {
Either::Left(b.values_mut().rev())
}
else {
Either::Right(b.values_mut())
};
Также в случае, если вам просто нужно распечатать итератор в определенном направлении на основе флага, это можно сделать без внешних крейтов следующим образом:
fn main() {
let numbers = vec![1, 2, 3, 4, 5, 6];
print(&numbers, false);
print(&numbers, true);
}
fn print(what: &[i32], reverse: bool) {
//match statement condition check
match reverse {
true => {
for n in what.iter().rev() {
println!("{n}");
}
},
false => {
for n in what.iter() {
println!("{n}");
}
},
}
}