英文:
How do I conditionally iterate in reverse?
问题
以下是您提供的代码的翻译部分:
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}");
}
}
这是您收到的错误:
// 错误:
类型不匹配
期望结构体 `std::slice::Iter<&'_ , _>`
找到结构体 `Rev<std::slice::Iter<'_, _>>`
您想要实现所需行为的方法是令iter
的类型一致。在Rust中,可以使用Box<dyn Iterator>
来处理这种情况。这里是修复后的代码:
fn main() {
let numbers = vec![1, 2, 3, 4, 5, 6];
print(&numbers, false);
print(&numbers, true);
}
fn print(what: &[i32], reverse: bool) {
let mut iter: Box<dyn Iterator<Item = &i32>> = if reverse {
Box::new(what.iter().rev())
} else {
Box::new(what.iter())
};
while let Some(n) = iter.next() {
println!("{:?}", n);
}
}
这段代码将允许您在基于布尔参数的条件下切换迭代器的方向,而不会出现类型不匹配的错误。
英文:
I want to switch the direction of an iterator based on a boolean parameter. I tried the following approach, but it ends with a compile error:
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}");
}
}
This is the error I receive:
// Error:
mismatched types
expected struct `std::slice::Iter<'_, _>`
found struct `Rev<std::slice::Iter<'_, _>>`
How could I implement my desired behavior?
答案1
得分: 1
You can do it using dynamic dispatch as explained here like so:
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.
}
}
}
and the rustexplorer link.
However, as already noted in the linked thread above, it is probably easier and better to use an enum (crate) like either like so:
let mut iter =
if reverse {
Either::Left(b.values_mut().rev())
}
else {
Either::Right(b.values_mut())
};
Also, in the case that you just need to print out the iterator in a certain direction based on a flag, this can be done without external crates as follows:
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}");
}
},
}
}
(Note: The code you provided contains HTML escape codes, which I've left as is.)
英文:
You can do it using dynamic dispatch as explained here like so:
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.
}
}
}
and the rustexplorer link.
However as already noted in the linked thread above, it is probably easier and better to use an enum (crate) like either like so
let mut iter =
if reverse {
Either::Left(b.values_mut().rev())
}
else {
Either::Right(b.values_mut())
};
Also in the case that you just need to print out the iterator in a certain direction based on a flag this can be done without external crates as follows:
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}");
}
},
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论