簡體   English   中英

這是從文件中讀取行並將其拆分為Rust中的單詞的正確方法嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM