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

后端 未结 2 1533
孤独总比滥情好
孤独总比滥情好 2020-12-06 19:24

I\'m trying to read some lines from a file, skipping the first few and printing the rest, but I keep getting errors about used value after move:

use std::fs:         


        
相关标签:
2条回答
  • 2020-12-06 19:25

    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 use Iterator::take. This has to be driven to completion with a for loop though:

    use std::{
        fs::File,
        io::{self, BufRead, BufReader, Read},
        path::Path,
    };
    
    fn skip_and_print_file(skip: usize, path: impl AsRef<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(buffer);
        }
    }
    
    fn print_to_stdout(mut input: impl Read) {
        let mut stdout = io::stdout();
        io::copy(&mut input, &mut stdout).expect("Unable to copy");
    }
    
    fn main() {
        skip_and_print_file(2, "/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.

    0 讨论(0)
  • 2020-12-06 19:38

    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
    
    0 讨论(0)
提交回复
热议问题