Confrontiamo 4 approcci.
1. Read::chars
Si potrebbe copiare Read::chars
realizzazione, ma è contrassegnato instabile con
la semantica di un parziale di lettura/scrittura di cui gli errori accadono Attualmente non è chiaro e può cambiare
quindi è necessario prestare attenzione. Ad ogni modo, questo sembra essere l'approccio migliore.
2. flat_map
Il flat_map
alternativa non può essere compilato:
use std::io::{BufRead, BufReader};
use std::fs::File;
pub fn main() {
let mut f = BufReader::new(File::open("input.txt").expect("open failed"));
for c in f.lines().flat_map(|l| l.expect("lines failed").chars()) {
println!("Character: {}", c);
}
}
problemi è che chars
prende in prestito dalla stringa, ma solo l.expect("lines failed")
vita all'interno della chiusura, in modo compilatore dà l'errore borrowed value does not live long enough
.
3. nidificati per
Questo codice
use std::io::{BufRead, BufReader};
use std::fs::File;
pub fn main() {
let mut f = BufReader::new(File::open("input.txt").expect("open failed"));
for line in f.lines() {
for c in line.expect("lines failed").chars() {
println!("Character: {}", c);
}
}
}
opere, ma mantiene assegnazione una stringa per ogni linea. Inoltre, se non ci sono interruzioni di riga sul file di input, l'intero file verrebbe caricato nella memoria.
4.BufRead::read_until
Una memoria efficiente alternativa per avvicinarsi 3 è quello di utilizzare Read::read_until
, e utilizzare una singola stringa di leggere ogni riga:
use std::io::{BufRead, BufReader};
use std::fs::File;
pub fn main() {
let mut f = BufReader::new(File::open("input.txt").expect("open failed"));
let mut buf = Vec::<u8>::new();
while f.read_until(b'\n', &mut buf).expect("read_until failed") != 0 {
// this moves the ownership of the read data to s
// there is no allocation
let s = String::from_utf8(buf).expect("from_utf8 failed");
for c in s.chars() {
println!("Character: {}", c);
}
// this returns the ownership of the read data to buf
// there is no allocation
buf = s.into_bytes();
buf.clear();
}
}
Per alcuni tipi di file di testo:. 'F.lines() flat_map (| l | l.chars()) '... ma questa non è davvero una buona soluzione. –
Hai appena considerato di copiare l'implementazione nel frattempo? Sono solo ~ 100 linee e significa che il tuo codice sarà banale da aggiornare se 'chars' si stabilizza così com'è. – Veedrac