首页 文章

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

提问于
浏览
1

从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-夜间(00df3251f 2015-02-08 23:24:33 0000)

2 回答

  • 2

    你不能从一个函数返回一个裸 Iterator ,因为它是一个特征,因此不是一个大小的类型 .

    在您的情况下,您需要将迭代器对象放在一个框中,以使其成为可以从函数返回的大小对象 .

    为此,您可以像这样更改代码:

    fn get_args() -> Box<Iterator<Item=String> + 'static> {
        Box::new(std::env::args().filter_map(|arg| arg.into_string().ok()))
    }
    

    在这里,我为trait对象添加了一个生命周期说明符 'static ,这意味着它完全是自有的(在这种意义上,不带参数的函数几乎总会返回有效的 'static 生命周期) .

    您还需要 <Item=String> 部分来显示迭代器产生的数据类型 . 在这种情况下:字符串 .

  • 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()))
    }
    

相关问题