rust - 如何从文件向量创建单个流?

标签 rust

我正在尝试读取多个文件,并且想从文件路径的向量创建流。我已经和编译器进行了一段时间的战斗,但不确定如何使它起作用:

fn formatted_tags_stream(
    args: &[&str],
    files: &Vec<PathBuf>,
) -> Result<impl Iterator<Item = String>> {
    
    // Transform list of paths into a list of files
    let files: Vec<File> = files.into_iter().map(|f| File::open(f)).flatten().collect();

    // Here is where I'm stuck :/
    let stream =
        files
            .into_iter()
            .skip(1)
            .fold(BufReader::new(files[0]), |acc, mut f| acc.chain(f));

    Ok(BufReader::new(stream).lines().filter_map(|line| {
        line.ok().and_then(|tag| {
            if let Ok(tag) = serde_json::from_str::<TagInfo>(&tag) {
                Some(tag.format())
            } else {
                None
            }
        })
    }))
}

最佳答案

如果使用fold,则该函数必须始终返回相同的类型。但是,如果在编写时使用它,则该函数将采用F类型并在第一遍中返回Chain<F, ...>。下一遍将需要采用Chain<F, ...>并返回Chain<Chain<F, ...>, ...>-导致“每次迭代的类型不同”。这将不起作用,因为Rust想要知道确切的类型,并且该类型必须保持不变。
但是,您可以键入内容并将其隐藏在指针后面(即Box,添加“特质对象”)。参见here (I did some minor adjustments to make it compile):

use std::path::PathBuf;
use std::fs::File;
use std::io::BufReader;
use std::io::Read;
use std::io::BufRead;

fn formatted_tags_stream(
    args: &[&str],
    files: &Vec<PathBuf>,
) -> Result<impl Iterator<Item = String>, ()> {
    
    // Transform list of paths into a list of files
    let files: Vec<File> = files.into_iter().map(|f| File::open(f)).flatten().collect();

    // Here is where I'm stuck :/
    let bufreader = Box::new(std::io::empty()) as Box<dyn Read>;
    let stream =
        files
            .into_iter()
            .fold(bufreader, |acc, f| Box::new(acc.chain(f)) as Box<dyn Read>);

    Ok(BufReader::new(stream).lines().filter_map(|line| {
        line.ok().and_then(|tag| {
            if let Ok(_tag) = tag.parse::<usize>() {
                Some(tag)
            } else {
                None
            }
        })
    }))
}
请注意,使用Box<dyn Read>会导致一些运行时开销,因为它会导致动态分配。

关于rust - 如何从文件向量创建单个流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64439679/

相关文章:

rust - 如何在 Rust 中将有符号整数添加到无符号整数?

rust - 有没有办法在 Rust 中删除静态生命周期对象?

hashmap - 如何为我自己的结构实现 Eq 和 Hash 以将它们用作 HashMap 键?

rust - 无法在循环中递减 &BigUint,因为临时值的生命周期不够长

rust - 在递归函数中使用 impl Trait

rust - 期权类型和提前返回。 is_none() 时返回错误

rust - 在 Gentoo 上的 IntelliJ IDEA 中,由于 gentoo 不使用 rustup,我该如何附加 rust stdlib 源?

rust - 为什么Arc <Mutex <T >>需要T : Sync + Send?

arrays - 退出代码 101 使用 &array 遍历数组

rust - 在不同集合中使用 String 及其指针的安全有效方式