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::File;
use std::io::{self, BufRead, BufReader, Read};
use std::path::Path;
fn skip_and_print_file(skip: &usize, path: &Path) {
let mut skip: usize = *skip;
if let Ok(file) = File::open(path) {
let mut buffer = BufReader::new(file);
for (index, line) in buffer.lines().enumerate() {
if index >= skip {
break;
}
}
print_to_stdout(&mut buffer);
}
}
fn print_to_stdout(mut input: &mut Read) {
let mut stdout = io::stdout();
io::copy(&mut input, &mut stdout);
}
fn main() {}
This is the error I'm getting:
error[E0382]: use of moved value: `buffer`
--> src/main.rs:15:30
|
10 | for (index, line) in buffer.lines().enumerate() {
| ------ value moved here
...
15 | print_to_stdout(&mut buffer);
| ^^^^^^ value used here after move
|
= note: move occurs because `buffer` has type `std::io::BufReader<std::fs::File>`, which does not implement the `Copy` trait
In order to avoid the move, use the
Read::by_ref()
method. That way, you only borrow theBufReader
:As Lukas Kalbertodt says, use
Read::by_ref
.This prevents
lines
from consuming theBufReader
and instead it consumes a&mut BufReader
. The same logic applies to iterators.Instead of implementing
skip
yourself, you can just useIterator::take
. This has to be driven to completion with something likeIterator::count
though:Note that there's no reason to make the
skip
variable mutable or even to pass in a reference. You can also take inAsRef<Path>
and then callers ofskip_and_print_file
can just pass in a string literal.