鉴于以下内容:
use std::old_io::{BufferedReader, File};
struct Journal<T> where T: Buffer {
file: T,
}
impl<T: Buffer> Iterator for Journal<T> {
type Item = String;
fn next(&mut self) -> Option<String> {
match self.file.read_line() {
Ok(line) => Some(line.to_string()),
Err(_) => None,
}
}
}
fn main() {
let path = Path::new("/tmp/allocator-journal.txt");
let mut file = BufferedReader::new(File::open(&path));
let journal = Journal {file: file};
for line in journal {
print!("{}", line);
}
}
我想将文件打开逻辑移到Journal上的new
方法中。由于unable to infer enough type information about '_'; type annotations required [E0282]
:
use std::old_io::{BufferedReader, File, IoResult};
struct Journal<T> where T: Buffer {
file: T,
}
impl<T: Buffer> Journal<T> {
fn new() -> Journal<BufferedReader<IoResult<File>>> {
let path = Path::new("/tmp/allocator-journal.txt");
let mut file = BufferedReader::new(File::open(&path));
Journal {file: file}
}
}
impl<T: Buffer> Iterator for Journal<T> {
type Item = String;
fn next(&mut self) -> Option<String> {
match self.file.read_line() {
Ok(line) => Some(line.to_string()),
Err(_) => None,
}
}
}
fn main() {
let journal = Journal::new();
for line in journal {
print!("{}", line);
}
}
无法向变量绑定添加类型提示或方法调用(Journal::new::<Journal<BufferedReader<etc..>>>
)都无法解决问题。
为什么不能输入这种类型? Journal :: new的签名是明确的,对吧?
顺便说一句,为什么Journal::new()
的返回类型为Journal<T>
,其中T =缓冲区?
答案 0 :(得分:2)
您正在混合仿制药和非仿制药的世界(细节?)。这是修复:
impl Journal<BufferedReader<IoResult<File>>> {
fn new() -> Journal<BufferedReader<IoResult<File>>> {
let path = Path::new("/tmp/allocator-journal.txt");
let mut file = BufferedReader::new(File::open(&path));
Journal {file: file}
}
}
请注意此处缺少T
。重点是您决定T
必须是什么类型(BufferedReader<IoResult<File>>
),因此不需要类型变量。
通过拥有类型变量,编译器正试图找出T
应该是什么。但是,您不能在任何地方使用T
,因此没有任何内容可以连接点,并且您会收到错误说明。
这提出了一个问题:为什么要使用泛型?您实际上并没有将它们用于任何事情,因此您也可以将T
替换为BufferedReader<IoResult<File>>
无处不在。