如何编写传递给函数的迭代器的类型?

时间:2016-04-05 02:41:26

标签: loops parsing vector iterator rust

我正在尝试编写一个解析器,它将迭代器通过向量传递给函数。代码类似于:

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'

2 个答案:

答案 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>) {}