如何将明确的生命周期绑定应用于返回的特征?

时间:2015-02-10 17:04:30

标签: iterator rust

从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)

2 个答案:

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