![](/img/trans.png)
[英]Is using to_string the cleanest way to read a file by lines and split by whitespace?
[英]Is this the right way to read lines from file and split them into words in Rust?
編者注:此代碼示例來自1.0之前的Rust版本,並且在語法上不是有效的Rust 1.0代碼。 此代碼的更新版本會產生不同的錯誤,但答案仍包含有價值的信息。
我已經實現了以下方法來返回二維數據結構中的文件中的單詞:
fn read_terms() -> Vec<Vec<String>> {
let path = Path::new("terms.txt");
let mut file = BufferedReader::new(File::open(&path));
return file.lines().map(|x| x.unwrap().as_slice().words().map(|x| x.to_string()).collect()).collect();
}
這是Rust中正確的,慣用的和有效的方式嗎? 我想知道是否需要經常調用collect()
以及是否有必要在這里調用to_string()
來分配內存。 也許返回類型應該以不同的方式定義,以便更具慣用性和效率?
從文本文件中獲取單詞的方式更短,更易讀。
use std::io::{BufRead, BufReader};
use std::fs::File;
let reader = BufReader::new(File::open("file.txt").expect("Cannot open file.txt"));
for line in reader.lines() {
for word in line.unwrap().split_whitespace() {
println!("word '{}'", word);
}
}
您可以將整個文件作為單個String
讀取,然后構建一個指向內部單詞的引用結構:
use std::io::{self, Read};
use std::fs::File;
fn filename_to_string(s: &str) -> io::Result<String> {
let mut file = File::open(s)?;
let mut s = String::new();
file.read_to_string(&mut s)?;
Ok(s)
}
fn words_by_line<'a>(s: &'a str) -> Vec<Vec<&'a str>> {
s.lines().map(|line| {
line.split_whitespace().collect()
}).collect()
}
fn example_use() {
let whole_file = filename_to_string("terms.txt").unwrap();
let wbyl = words_by_line(&whole_file);
println!("{:?}", wbyl)
}
這將以較少的開銷讀取文件,因為它可以將其插入單個緩沖區,而使用BufReader
讀取行意味着需要大量復制和分配,首先進入BufReader
內的緩沖區,然后進入每行新分配的String
,以及然后進入一個新分配的每個單詞的String
。 它也將使用更少的內存,因為單個大型String
和引用向量比許多單獨的String
更緊湊。
缺點是你不能直接返回引用的結構,因為它不能通過堆棧框架來保存單個大的String
。 在上面的example_use
,我們必須將大型String
放入let
中以調用words_by_line
。 使用不安全的代碼並將String
和引用包裝在私有結構中是可能的,但這要復雜得多。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.