【问题标题】:How to avoid filter_map() gives error "returns a value referencing data owned by the current function" in Rust?如何避免 filter_map() 在 Rust 中给出错误“返回引用当前函数拥有的数据的值”?
【发布时间】:2026-02-03 03:25:01
【问题描述】:

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

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

我知道我不能返回引用函数拥有的数据的值。但我不知道如何在这里避免它。当line 的类型是&str 时,它可以工作。但是在这里,line 的类型是std::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));
}

【问题讨论】:

    标签: rust lifetime borrowing


    【解决方案1】:

    在你的映射闭包中,line 的类型是Result<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));
    

    【讨论】:

    • 谢谢@Peter。这正是要寻找的东西。谢谢你的详细解释。
    【解决方案2】:
    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)
                   // Cannot returns referencing `&str` owned by the current function(closure),
                   // but a owned captured substring here
                   .map(|cap| cap[1].to_string())
            })
            .for_each(|x| println!("{}", x));
    }
    

    【讨论】: