假设我有一个字符串,我在它的字符上创建一个迭代器(可循环、可查看):
let hello = "hello";
let mut iterator = hello.chars().cycle().peekable;
Run Code Online (Sandbox Code Playgroud)
我想弄清楚 的类型iterator是什么,所以我故意引入了一个错误:
let mut iterator: usize = hello.chars().cycle().peekable;
然后编译器告诉我右侧的类型是:
std::iter::Peekable<std::iter::Cycle<std::str::Chars<'_>>>
Run Code Online (Sandbox Code Playgroud)
哇,真是一口。如果我像这样定义一个函数:
fn foobar(x: std::iter::Peekable<std::iter::Cycle<std::str::Chars<'_>>>){
// snip
}
Run Code Online (Sandbox Code Playgroud)
我收到这样的错误:
error: underscore lifetimes are unstable (see issue #44524)
Run Code Online (Sandbox Code Playgroud)
那么,如果我想将迭代器传递给函数,我应该怎么做呢?或者,这是我应该避免的事情吗?
好的,这个问题有多个方面:
首先,您可以通过给它一个显式的生命周期来避免编译器错误:
fn foobar<'a>(mut x: std::iter::Peekable<std::iter::Cycle<std::str::Chars<'a>>>){
Run Code Online (Sandbox Code Playgroud)
对于第二个问题,无论这是否惯用,我都会说不,避免这种特定的方法。
您只能传入这个特定的迭代器链 - 其他的都是不可能的。但大多数时候,您的算法对特定组合不感兴趣,而不是“生成”字符的功能。使用泛型或impl Trait替代(如果您可以使用 nightly rust)。
Impl Trait 是一项功能,允许隐藏所使用的特定类型。在撰写本文时,这一特定功能在几天前(在撰写本文时)已在参数位置中接受 impl 特征。我制作了这个快速草图用于演示目的,游乐场链接
#![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)
}
Run Code Online (Sandbox Code Playgroud)
编辑:您也可以使用泛型,请参阅 nullqube 和 stefan 的评论