我正在尝试编写一个解析器,它将迭代器通过向量传递给函数。代码类似于:
fn foo(itr : ???) {
while let Some(c) = itr.next() {
if *c != 0 {
break;
}
println!("{}", *c);
}
}
fn main() {
let v = vec![0; 10];
let itr = v.iter();
while let Some(c) = itr.next() {
foo(itr);
}
}
我不确定如何在向量上写入迭代器的类型。我尝试使用错误的类型u32
来查看期望的rustc
类型:core::slice::Iter<'_, _>
。当我尝试使用core::slice
rustc抱怨Use of undeclared type or module 'core::slice'
答案 0 :(得分:3)
有许多类型的迭代器;大多数时候,你真正想要的是一个能够消耗其中任何一个的功能。要做到这一点,惯用的解决方案是使用泛型。
fn foo<'a, T: Iterator<Item=&'a i32>>(mut itr: T) {
while let Some(c) = itr.next() {
if *c != 0 {
break;
}
println!("{}", *c);
}
}
fn main() {
let v = vec![0; 10];
let mut itr = v.iter();
while let Some(c) = itr.next() {
foo(itr);
}
}
上面的代码虽然没有编译,因为它将itr
移动到foo
,然后尝试在while let
上再次使用它。要解决这个问题,我们需要通过引用传递迭代器。
fn foo<'a, T: Iterator<Item=&'a i32>>(itr: &mut T) {
while let Some(c) = itr.next() {
if *c != 0 {
break;
}
println!("{}", *c);
}
}
fn main() {
let v = vec![0; 10];
let mut itr = v.iter();
while let Some(c) = itr.next() {
foo(&mut itr);
}
}
我们也可以使用特征对象代替泛型:
fn foo<'a>(itr: &mut Iterator<Item=&'a i32>) {
while let Some(c) = itr.next() {
if *c != 0 {
break;
}
println!("{}", *c);
}
}
fn main() {
let v = vec![0; 10];
let mut itr = v.iter();
while let Some(c) = itr.next() {
foo(&mut itr);
}
}
Rust书中关于trait objects的章节解释了这些解决方案之间的区别。
答案 1 :(得分:0)
解决方案是添加
use std::slice::Iter;
,类型是
fun foo<'a>(itr : &mut Iter<'a, i32>) {}