gpt4 book ai didi

types - 克隆特性 BufRead 的行时类型不匹配

转载 作者:行者123 更新时间:2023-11-29 08:27:22 28 4
gpt4 key购买 nike

为了更好地使用 Rust,我决定实现一个简单的词法分析器来逐行分析一些文档。

因为我必须在特性 BufRead 的行上至少迭代两次,所以我正在克隆我的 BufRead 的行,但我得到以下错误:

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 == &_`

我明白错误是什么,但基于 following code ,如何告诉编译器 IteratorItem 应该是什么,以便它可以正确转换类型?

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!(),
}
}

出于单元测试的目的,我正在构建一个带有 String 的缓冲区,但在正常使用中,我是从 File 中读取它的。

最佳答案

查看 Iterator::cloned定义:

fn cloned<'a, T>(self) -> Cloned<Self> 
where Self: Iterator<Item=&'a T>,
T: 'a + Clone

以及Iterator 的实现io::Lines :

impl<B: BufRead> Iterator for Lines<B> {
type Item = Result<String>;
}

您不能使用 cloned,因为迭代器项不是引用。否则你不能“告诉”编译器;这不是类型的工作方式。

As I have to iterate at least two times over the lines of the trait BufRead, I am cloning the lines of my BufRead

这真的没有意义。克隆读者的行不会节省任何东西。事实上,它可能只会让事情变得更糟。您将创建一次字符串,除了克隆它们之外不使用它们,然后在您再次迭代时第三次创建它们。

如果您希望避免重新创建所有字符串,请将所有字符串收集Vec 或其他集合中,然后迭代多次:

pub fn analyze<T: BufRead>(document: T) -> Result<DocumentMetadata, ()> {
let lines: Result<Vec<_>, _> = document.lines().collect();
let lines = lines.unwrap();
let language = guess_language(&lines);

// Do more lexical analysis based on document language

Ok(DocumentMetadata {
language: language,
// ...
})
}

fn guess_language<'a, I>(lines: I) -> String
where I: IntoIterator<Item = &'a String>,
{
for line in lines {
// Try to guess language
}
"en".to_string()
}

关于types - 克隆特性 BufRead 的行时类型不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42239398/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com