gpt4 book ai didi

rust - 改变循环中的两个相关值

转载 作者:行者123 更新时间:2023-11-29 08:22:10 28 4
gpt4 key购买 nike

我尝试以一种足以满足我的目的的方式读取文件。我有一个文件 ID、名称和行索引(有序)的列表,对于每一对 (file_id, file_name, line_index) 我需要打开文件,按索引找到行并打印。

为了提高性能(我知道输入是有序的),我想缓存按行读取的 BufReader 并尽可能让文件保持打开状态。

fn main() {
// positions in file
// structure: (file_id, file_name, line_index_in_file)
let positions = &vec![
(1, String::from("file1"), 1),
(1, String::from("file1"), 2),
(1, String::from("file1"), 20),
(2, String::from("file2"), 15)];

print_lines_from_file(&positions);
}

fn print_lines_from_file(found: &Vec<(i32, String, i32)>) {
let mut last_file_id = -1;

//let mut last_file_name = None;
let mut open_file = None;
let mut open_reader = None;

for &(file_id, ref file_name, pos_in_file) in found {
println!("{} {}", file_id, pos_in_file);

if last_file_id < file_id {
last_file_id = file_id;
//last_file_name = file_ids.get(&file_id);

if let Some(to_close) = open_file {
drop(open_reader.unwrap());
drop(to_close);
}
//let file = File::open(last_file_name.unwrap()).unwrap();
let file = File::open(file_name).unwrap();
open_file = Some(file);
open_reader = Some(BufReader::new(&file));
}

// use reader to find the line in file and process
}
}

我遇到了这个问题:

main.rs:40:48: 40:52 error: `file` does not live long enough
main.rs:40 open_reader = Some(BufReader::new(&file));

main.rs:40:48: 40:52 error: use of moved value: `file` [E0382]
main.rs:40 open_reader = Some(BufReader::new(&file));

这很明显(file 的生命周期真的很短),但我不知道如何解决它。BufReader 依赖于 File,但当 file_id 更改时,我需要稍后在循环中关闭 File

另外,我觉得在循环中以这种方式调用 drop 并不是很舒服,因为在我看来,这就像我试图愚弄编译器一样。这种方法可以吗?

即使您知道更好的解决方案(例如如何通过 BufReader 关闭文件,我也会很感激如何解决它的一般见解)。

最佳答案

您可以将 File 按值传递给 BufReader。这样你就只有一个拥有文件句柄的变量。您可以在 Option 上使用 take 将内部值移出它并留下一个 None。这样你可以确保文件句柄在下一个文件被获取之前被释放(所以如果你重新打开同一个文件它不会 panic )

let mut open_reader = None;

for &(file_id, ref file_name, pos_in_file) in found {
println!("{} {}", file_id, pos_in_file);

if last_file_id < file_id {
last_file_id = file_id;
//last_file_name = file_ids.get(&file_id);

// take the value out of the `open_reader` to make sure that
// the file is closed, so we don't panic if the next statement
// tries to open the same file again.
open_reader.take();
//let file = File::open(last_file_name.unwrap()).unwrap();
let file = File::open(file_name).unwrap();
open_reader = Some(BufReader::new(file));
}

// use reader to find the line in file and process
}

关于rust - 改变循环中的两个相关值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37726317/

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