Как получить доступ к BufReader дважды? - PullRequest
2 голосов
/ 16 июня 2019

Попытка доступа к переменной предложения во второй раз приводит к 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 ]

3 голосов
/ 16 июня 2019

Вы не можете получить доступ к значению, если право собственности было перенесено ранее.Однако вы можете проверять свои строки с помощью 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);
}

Детская площадка

Таким образом, вам не нужно читатьподать дважды.Вы только повторяете это дважды.

2 голосов
/ 16 июня 2019

Вы не можете. Вам нужно прочитать файл дважды. Сначала подсчитать общее количество строк. И второй обработать каждую строку. Итак, вам нужно два 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);
}
0 голосов
/ 17 июня 2019

sentences.lines() - итератор. Вы можете одолжить его вместо потребления, позвонив по номеру .by_ref():

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