我想逐行读取文件:
'#'
开头的行我尝试了两种不同的方法,但我认为我对Rust的理解不足以正确编写它。
我将文件保存到BufReader
,还使用BufReader
通过引用获取了by_ref
。
我的问题是我不知道怎么说“我不想只读取第一个字节就修改行”。我还尝试了字符串的字节表示形式,但是对于代码示例来说看起来很丑
use std::{
fs::File,
io::{self, BufRead, BufReader, Read},
};
fn main() -> io::Result<()> {
let fname = "/etc/hosts";
let file = File::open(fname)?;
let mut br = BufReader::new(file);
for line in br.by_ref().lines() {
if line.unwrap().starts_with("#") {
continue;
}
println!("{}", line?);
}
Ok(())
}
每次都会出现编译器响应:“我无法给您该行,因为它已被移动以进行检查...”。
error[E0382]: use of moved value: `line`
--> src/main.rs:15:24
|
11 | for line in br.by_ref().lines() {
| ---- move occurs because `line` has type `std::result::Result<std::string::String, std::io::Error>`, which does not implement the `Copy` trait
12 | if line.unwrap().starts_with("#") {
| ---- value moved here
...
15 | println!("{}", line?);
| ^^^^ value used here after move
我认为我可以使用过滤器。我不想走这样的路,因为大多数有更多顺序编程习惯的人不喜欢对这些操作(例如文件操作)使用功能模式。我们更喜欢控制缓冲区的大小,以及何时发生什么情况,而功能方法通常会使难度变得更大。
我以为我应该发布的信息是,我知道这可以通过功能性的方式来完成,但是在我编写并运行它之后,它又遇到了同样的问题...
use std::{
fs::File,
io::{self, BufRead, BufReader},
};
fn main() -> io::Result<()> {
let fname = "/etc/hosts";
let file = File::open(fname)?;
let lines: io::Result<std::string::String> = BufReader::new(file)
.lines()
.filter(|x| x.unwrap().starts_with('#'))
.collect();
for line in lines {
println!("{}", line);
}
Ok(())
}
我遇到一个错误:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:12:21
|
12 | .filter(|x| x.unwrap().starts_with('#'))
| ^ cannot move out of borrowed content
将lambda参数x
更改为引用将导致借入,这将引起编译器的另一响应:cannot move out of borrowed content
。
是否有任何简单的方法可以编写此类模式,而无需每次都复制值?