将迭代器作为参数传递给函数反模式?

时间:2017-12-02 08:12:04

标签: rust

假设我有一个字符串,我可以在其字符串上创建一个迭代器(可循环使用,可以查看):

string DB "My string", 0

我想知道let hello = "hello"; let mut iterator = hello.chars().cycle().peekable; 的类型是什么,所以我故意引入了一个错误:

iterator

然后编译器通知我右侧的类型是:

let mut iterator: usize = hello.chars().cycle().peekable;
哇,哎呀。如果我定义一个这样的函数:

std::iter::Peekable<std::iter::Cycle<std::str::Chars<'_>>>

我收到这样的错误:

fn foobar(x: std::iter::Peekable<std::iter::Cycle<std::str::Chars<'_>>>){
    // snip
}

所以,如果我想将迭代器传递给函数,我应该怎么做?或者,这是我应该避免的吗?

1 个答案:

答案 0 :(得分:1)

好的,这个问题有多个方面:

首先,您可以通过为其提供明确的生命周期来避免编译器错误:

fn foobar<'a>(mut x: std::iter::Peekable<std::iter::Cycle<std::str::Chars<'a>>>){

对于他的第二个问题,这是否是惯用语,我会说不,避免采用这种具体方法。

你只能传递这个特定的迭代器链 - 其他东西是不可能的。但大多数情况下,您的算法对特定组合不感兴趣,而不是“生成”字符的功能。请改用genericsimpl Trait(如果您有夜间生锈的话)。

Impl Trait是一项功能,允许隐藏使用的特定类型。这个特定的特征,在几天前,在写作时,接受了论证位置中的impl特征。我为了演示目的制作了这个快速草图,playground link

#![feature(universal_impl_trait)]

fn main() {
    foo("hello".chars());
    foo("hello".chars().rev());
}

fn foo(x: impl Iterator<Item=char>) {
    let text: String = x.collect();
    println!("{}", &text)
}

编辑:您也可以使用泛型,请参阅nullqube和stefan的评论