Cannot use moved BufReader after for loop with bufreader.lines()

半世苍凉 提交于 2019-11-29 10:52:52

In order to avoid the move, use the Read::by_ref() method. That way, you only borrow the BufReader:

for (index, line) in buffer.by_ref().lines().enumerate() { ... }
//                         ^^^^^^^^^
// you can still use `buffer` here

As Lukas Kalbertodt says, use Read::by_ref.

This prevents lines from consuming the BufReader and instead it consumes a &mut BufReader. The same logic applies to iterators.

Instead of implementing skip yourself, you can just use Iterator::take. This has to be driven to completion with something like Iterator::count though:

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

fn skip_and_print_file(skip: usize, path: &Path) {
    if let Ok(file) = File::open(path) {
        let mut buffer = BufReader::new(file);

        for _ in buffer.by_ref().lines().take(skip) {}
        // Or: buffer.by_ref().lines().take(skip).for_each(drop);

        print_to_stdout(&mut buffer);
    }
}

fn print_to_stdout(mut input: &mut Read) {
    let mut stdout = io::stdout();
    io::copy(&mut input, &mut stdout).expect("Unable to copy");
}

fn main() {
    skip_and_print_file(2, Path::new("/etc/hosts"));
}

Note that there's no reason to make the skip variable mutable or even to pass in a reference. You can also take in AsRef<Path> and then callers of skip_and_print_file can just pass in a string literal.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!