解决在 Rust 中将 AsRef<Path> 参数传递给函数指针时的生命周期问题

问题描述 投票:0回答:1

我正在开发我的第一个 Rust 应用程序,并且遇到了与借用值相关的问题。我的应用程序涉及使用多个返回

Result<DataFrame, ParseError>
的函数来解析不同类型的文本文件。 DataFrame 来自 Polars 库,ParseError 是我的自定义错误类型。

我有多个具有以下签名的文件解析函数:

fn parse_file<P: AsRef<Path>>(file_path: P) -> Result<DataFrame, ParseError>

这允许我传递字符串切片或对 std::path::Path 的引用。

有时,我会单独调用这些文件解析函数。其他时候,我想解析目录中的所有文件,所以我需要一个可以解析整个目录的函数。为此,我打算将文件解析函数作为参数传递。

这是我当前的实现:

type ParseFunction<P> = fn(P) -> Result<DataFrame, ParseError>;
fn parse_folder<P: AsRef<Path>>(
    dir: P,
    parse_function: ParseFunction<&Path>,
) -> Result<HashMap<String, DataFrame>, ParseError> {
    let mut map: HashMap<String, DataFrame> = HashMap::new();
    for entry in fs::read_dir(dir).map_err(|_| ParseError::ReadFolderError)? {
        let file = entry.map_err(|_| ParseError::ReadFolderError)?;
        let filename = file.file_name().to_string_lossy().into_owned();
        let path = file.path().clone();
        if filename.ends_with(".art") {
            map.insert(
                filename,
                parse_function(&path)?,
            ); 
        } //parse_function should be done with path here
    } //path is dropped here. Why is that not ok? 
    Ok(map)
}

这会产生错误:错误[E0597]:

path
寿命不够长

为什么 Rust 在这种情况下会给我错误“路径生存时间不够长”,以及编写 parse_folder 函数来处理这个借用问题的正确方法是什么?

我主要想了解借贷问题。我尝试了很多不同的事情。法学硕士不断自信地提出不起作用的建议。

这是我想如何使用 parse_folder 函数的示例:

pub fn parse_art_file<P: AsRef<Path>>(
    file_path: P,
) -> Result<DataFrame, ParseError> {
    match read_and_decode_lines(&file_path) {
        // Attempt to read article parameters from the decoded lines
        Ok(lines) => read_article_parameters(lines),
        // Return an error if the file could not be read and decoded
        Err(_) => Err(ParseError::InvalidFile(file_path.as_ref().to_string_lossy().into_owned())),
    }
}

pub fn parse_art_folder<P: AsRef<Path>> (dir: P) -> Result<HashMap<String, DataFrame>, ParseError> {
    parse_folder(dir, parse_art_file)
}
rust path borrow-checker
1个回答
0
投票

parse_folder
中,
path
的类型是
PathBuf
(具有
impl AsRef<Path>
)。您可以直接传递
&path
,而不是将
parse_function
传递给
path

fn parse_folder<P: AsRef<Path>>(
    dir: P,
    parse_function: fn(file_path: PathBuf) -> Result<DataFrame, ParseError>,
) -> Result<HashMap<String, DataFrame>, ParseError> {
    let mut map: HashMap<String, DataFrame> = HashMap::new();
    for entry in fs::read_dir(dir).map_err(|_| ParseError::ReadFolderError)? {
        let file = entry.map_err(|_| ParseError::ReadFolderError)?;
        let filename_os = file.file_name();
        let filename = filename_os.to_string_lossy();
        if filename.ends_with(".art") {
            map.insert(filename.to_string(), parse_function(file.path())?);
        }
    }
    Ok(map)
}

我还将调用

to_owned/to_string
的地方也移到了if语句中。

© www.soinside.com 2019 - 2024. All rights reserved.