从Rust中的函数返回一个迭代器是一个Sisyphean维度的练习,但是我被告知它可以将一个作为特征返回而没有那么多的痛苦。不幸的是,它不起作用:显然,我需要明确的终身限制?这显然与添加生命周期参数不同。这意味着我不知道该怎么做。
这是我的(小的,测试的)代码:
fn main() {
let args = get_args();
for arg in args {
println!("{}", arg);
}
}
fn get_args() -> Iterator {
std::env::args().filter_map(|arg| arg.into_string().ok())
}
实际上工作的适当方法是什么?
编辑:锈版版本rustc 1.0.0-nightly(00df3251f 2015-02-08 23:24:33 +0000)
答案 0 :(得分:2)
你不能从函数中返回一个Iterator
,因为它是一个特征,因此不是一个大小的类型。
在您的情况下,您需要将迭代器对象放在一个框中,以使其成为可以从函数返回的大小对象。
为此,您可以像这样更改代码:
fn get_args() -> Box<Iterator<Item=String> + 'static> {
Box::new(std::env::args().filter_map(|arg| arg.into_string().ok()))
}
在这里,我为特征对象添加了一个生命周期说明符'static
,这意味着它完全是自有的(不带参数的函数几乎总会返回对'static
有效的函数。在这个意义上的一生。)
您还需要<Item=String>
部分来显示迭代器产生的数据类型。在这种情况下:字符串。
答案 1 :(得分:0)
在这种特定情况下,您可以设法从get_args返回具体类型,如下所示:
fn get_args() -> FilterMap<Args, fn(OsString) -> Option<String>> {
fn arg_into_string(arg: OsString) -> Option<String> { arg.into_string().ok() }
args().filter_map(arg_into_string as fn(OsString) -> Option<String>)
}
基本上这适用于你在迭代器适配器中使用的闭包(在你的情况下是filter_map)实际上不是一个闭包的所有情况,因为它不捕获任何环境,并且它可以由一个普通的旧函数建模
通常,如果确实需要返回包含闭包的类型,则确实需要将其打包并返回特征对象。在你的情况下:
fn get_args() -> Box<Iterator<Item=String> + 'static> {
Box::new(std::env::args().filter_map(|arg| arg.into_string().ok()))
}