如何两次访问BufReader?

时间:2019-06-16 15:32:22

标签: loops rust iterator

第二次尝试访问变量句子会导致value used here after move,我想了解如何存储总数而不引起此问题。

我试图复制迭代器,但找不到使它起作用的方法或正确的方法。

extern crate regex;

use std::fs::File;
use std::path::Path;
use std::io::{BufReader, BufRead};

fn main() {
    let sentences_path = Path::new("csv/testSentences.csv");
    let sentences = BufReader::new(File::open(&sentences_path).unwrap());

    let total = sentences.lines().count();

    for (index, sentence) in sentences.lines().enumerate() {
        let line = sentence.unwrap();
        println!("Processed {} of {}, {}", index, total, line);
    }

    println!("Total {}", total);
}

3 个答案:

答案 0 :(得分:3)

如果所有权先前已移动,则无法访问该值。但是,您可以使用inspect检查行,而无需更改内部行,而仅更新计数。

通过迭代线找出count之后,您可以再次对其进行迭代,并根据需要执行逻辑。

出现此编译器错误的主要原因是:count函数消耗了您使用的行,并且您的变量已被消耗,因此无法再次访问。

这是解决方案:

use std::fs::File;
use std::io::{BufRead, BufReader, Write};

fn main() {
    let path = "lines.txt";

    let mut output = File::create(path).unwrap();
    write!(output, "Rust\n?\nFun").unwrap();

    let input = File::open(path).unwrap();
    let buffered = BufReader::new(input);

    let lines: Vec<_> = buffered.lines().collect();
    let total = lines.len();

    for (index, sentence) in lines.into_iter().enumerate() {
        let line = sentence.unwrap();
        println!("Processed {} of {}, {}", index, total, line);
    }

    println!("Total {}", total);
}

Playground

通过这种方式,您无需读取文件两次。您只需重复两次。

答案 1 :(得分:2)

不能。您需要读取文件两次。首先计算总行数。其次处理每条线。因此,您需要两个BufReader

extern crate regex;                                                                                                     

use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;

fn get_file_reader(path: &Path) -> impl BufRead {
    BufReader::new(File::open(path).unwrap())
}

fn main() {
    let sentences_path = Path::new("csv/testSentences.csv");
    let sentences = get_file_reader(&sentences_path);

    let total = get_file_reader(&sentences_path).lines().count();

    for (index, sentence) in sentences.lines().enumerate() {
        let line = sentence.unwrap();
        println!("Processed {} of {}, {}", index, total, line);
    }

    println!("Total {}", total);
}

答案 2 :(得分:-1)

sentences.lines()是一个迭代器。您可以借用它而不是通过调用.by_ref()来消耗它:

let mut lines = sentences.lines();
let total = lines.by_ref().count();
for (index, sentence) in lines.enumerate() {
    // ...
}