假设我有一个字符串,我可以在其字符串上创建一个迭代器(可循环使用,可以查看):
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
}
所以,如果我想将迭代器传递给函数,我应该怎么做?或者,这是我应该避免的吗?
答案 0 :(得分:1)
好的,这个问题有多个方面:
首先,您可以通过为其提供明确的生命周期来避免编译器错误:
fn foobar<'a>(mut x: std::iter::Peekable<std::iter::Cycle<std::str::Chars<'a>>>){
对于他的第二个问题,这是否是惯用语,我会说不,避免采用这种具体方法。
你只能传递这个特定的迭代器链 - 其他东西是不可能的。但大多数情况下,您的算法对特定组合不感兴趣,而不是“生成”字符的功能。请改用generics或impl 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的评论