如何避免 Rust 中的 filter_map() 给出错误“返回引用当前函数拥有的数据的值”?

pel*_*cid 5 lifetime rust borrowing

我正在尝试使用filter_map. 下面的函数创建一个BufReadthen 选择与正则表达式匹配的行。我期望输出为"aaa",但编译器给了我错误:

returns a value referencing data owned by the current function" at line 7 `reg.captures(ss)`.
Run Code Online (Sandbox Code Playgroud)

我知道我无法返回引用函数拥有的数据的值。但我不知道如何避免这里。当 的类型line是 a时&str,它起作用。但在这里, 的类型linestd::string::String.

您能给我一些提示或指导我查看一些文件吗?我已阅读一些文档,但不明白如何避免该错误。

use regex::Regex; // 1.4.1
use std::io::{self, BufRead as _};

fn main() {
    let reg = Regex::new(r"^(a+)").unwrap();
    io::Cursor::new(b"aaa\nbbb\nccc")
        .lines()
        .filter_map(|line| {
            let ss = &line.unwrap()[..];
            reg.captures(ss)
        })
        .map(|cap| cap[1].to_string())
        .for_each(|x| println!("{}", x));
}
Run Code Online (Sandbox Code Playgroud)

Pet*_*all 3

在映射闭包内, 的类型lineResult<String, _>,这意味着它拥有String. 但是,reg.captures()返回一个包含对该字符串中切片的引用的值。函数无法返回对其所拥有的值的引用,因为当函数返回时这些值将被删除,从而使引用无效。

由于您要在无论如何之后立即创建一个新的拥有值filter_map,因此您可以将该部分移到内部,以便该引用仅在闭包内使用:

io::Cursor::new(b"aaa\nbbb\nccc")
    .lines()
    .filter_map(|line| {
        let ss = &line.unwrap()[..];
        reg.captures(ss).map(|cap| cap[1].to_string())
    })
    .for_each(|x| println!("{}", x));
Run Code Online (Sandbox Code Playgroud)