gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 11:41:34 25 4
gpt4 key购买 nike

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

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com