Um mit Rust besser zu werden, habe ich beschlossen, einen einfachen Lexer zu implementieren, der einige Dokumente Zeile für Zeile analysiert.Typenkonflikt beim Klonen der Linien des Features BufRead
Da ich mindestens zweimal über die Linien des Merkmals iterieren BufRead
, ich bin die Linien meiner BufRead
Klonen, aber ich erhalte den folgenden Fehler:
error[E0271]: type mismatch resolving `<std::io::Lines<T> as std::iter::Iterator>::Item == &_`
--> <anon>:18:23
|
18 | let lines = lines.cloned();
| ^^^^^^ expected enum `std::result::Result`, found reference
|
= note: expected type `std::result::Result<std::string::String, std::io::Error>`
= note: found type `&_
error[E0271]: type mismatch resolving `<std::io::Lines<T> as std::iter::Iterator>::Item == &_`
Ich verstehe, was der Fehler ist, aber basierend auf der following code, wie kann ich dem Compiler sagen, was die Item
der Iterator
sein sollte, so kann es den Typ richtig zu werfen?
use std::fmt::Write;
use std::io::{BufRead, BufReader, Lines, Read};
pub struct DocumentMetadata {
language: String,
// ...
}
pub fn analyze<T: BufRead>(document: T) -> Result<DocumentMetadata,()> {
let lines = document.lines();
let language = guess_language(&lines);
// Do more lexical analysis based on document language
Ok(DocumentMetadata {
language: language,
// ...
})
}
fn guess_language<T: BufRead>(lines: &Lines<T>) -> String {
let lines = lines.cloned();
for line in lines {
let line = line.unwrap();
// Try to guess language
}
"en".to_string()
}
#[test]
fn it_guesses_document_language() {
let mut document = String::new();
writeln!(&mut document, "# language: en").unwrap();
let document = BufReader::new(document.as_str().as_bytes());
match analyze(document) {
Ok(metadata) => assert_eq!("en".to_string(), metadata.language),
Err(_) => panic!(),
}
}
Für Testzwecke Einheit, Ich baue einen Puffer mit einem String
aber in einem normalen Gebrauch las ich es von einem File
.
auf diese Weise mehr Sinn macht, in der Tat. Ich hatte die Idee, die Zeilen zu klonen, weil die meisten Methoden von 'io :: Lines 'den Iterator konsumieren und ich dachte nicht, dass' collect' an die Situation angepasst wäre. Vielen Dank! – Ianlet