提问人:Joël Abrahams 提问时间:2/6/2023 更新时间:5/9/2023 访问量:414
为什么 Rust 书中 BufRead 的有效示例是有效的?
Why is the efficient example of BufRead in the Rust book, efficient?
问:
Rust 书给出了两个(与此相关)如何使用 .
他们首先给出一个“初学者友好”的例子,然后再采用更“有效的方法”。BufRead
初学者友好的示例逐行读取文件:
use std::fs::File;
use std::io::{ self, BufRead, BufReader };
fn read_lines(filename: String) -> io::Lines<BufReader<File>> {
// Open the file in read-only mode.
let file = File::open(filename).unwrap();
// Read the file line by line, and return an iterator of the lines of the file.
return io::BufReader::new(file).lines();
}
fn main() {
// Stores the iterator of lines of the file in lines variable.
let lines = read_lines("./hosts".to_string());
// Iterate over the lines of the file, and in this case print them.
for line in lines {
println!("{}", line.unwrap());
}
}
“有效方法”的作用几乎相同:
use std::fs::File;
use std::io::{self, BufRead};
use std::path::Path;
fn main() {
// File hosts must exist in current path before this produces output
if let Ok(lines) = read_lines("./hosts") {
// Consumes the iterator, returns an (Optional) String
for line in lines {
if let Ok(ip) = line {
println!("{}", ip);
}
}
}
}
// The output is wrapped in a Result to allow matching on errors
// Returns an Iterator to the Reader of the lines of the file.
fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
where P: AsRef<Path>, {
let file = File::open(filename)?;
Ok(io::BufReader::new(file).lines())
}
锈蚀书对后者说:
此过程比在内存中创建字符串更有效,尤其是处理较大的文件。
虽然后者稍微干净一些,但使用 instead instead to ,为什么返回一个更有效?
我假设一旦我们在第二个示例(in )中解开迭代器,性能方面它应该与第一个示例相同。
那为什么会有所不同呢?
为什么第二个示例中的迭代器每次都返回结果?if let
unwrap
Result
if let Ok(lines) = read_lines("./hosts")
答:
你是对的,“初学者友好”方法的效率同样低,并且不会“在内存中创建字符串”。似乎我们中的许多人都感到困惑。
目前至少有两个拉取请求试图解决混淆,也许你可以对你喜欢的拉取请求发表评论:
- https://github.com/rust-lang/rust-by-example/pull/1679
- https://github.com/rust-lang/rust-by-example/pull/1681
这两个拉取请求都修改了初学者友好的方法,以使用 read_to_string
而不是 .BufRead
read_to_string
使初学者友好的方法“效率低下”,正如 #1641 中的文本所建议的那样。
read_to_string
还给出了一个“在内存中创建字符串”的真实示例。有趣的是,“在内存中创建一个字符串”这句话从第一次提交就存在了......
...起初,这句话只描述了一种效率较低的假设方法......
...然后 #1641 以适合初学者的方法给出了一些实际代码......但它的效率同样低下!...
...在 #1679 或 #1681 之前,从未有过实际代码演示效率较低的方法!
评论
String
P: AsRef<Path>
String
BufReader