如何在迭代器的收集语句中放置类型注释?
How to put a type annotation in an iterator's collect statement?
我有这个代码:
use std::fs::File;
use std::io::{BufRead, BufReader};
fn load_file() -> Vec<String> {
let file = BufReader::new(File::open("foo.txt").unwrap());
file.lines().map(|x| x.unwrap()).collect();
}
fn main() {
let data = load_file();
println!("DATA: {}", data[0]);
}
当我尝试编译它时,出现此错误:
error[E0283]: type annotations required: cannot resolve `_: std::iter::FromIterator<std::string::String>`
--> src/main.rs:6:38
|
6 | file.lines().map(|x| x.unwrap()).collect();
| ^^^^^^^
事实上,如果我这样改变load_file
函数,代码编译顺利:
fn load_file() -> Vec<String> {
let file = BufReader::new(File::open("foo.txt").unwrap());
let lines: Vec<String> = file.lines().map(|x| x.unwrap()).collect();
return lines;
}
此解决方案 "Rusty" 不够,因为不鼓励以 return 结束函数。
有没有办法将类型注释直接放入 file.lines().map(|x| x.unwrap()).collect();
语句中?
Iterator::collect
's signature 看起来像这样:
fn collect<B>(self) -> B
where
B: FromIterator<Self::Item>,
在你的情况下,你需要告诉它 B
是什么。要指定通用函数的类型,您可以使用称为 turbofish 的语法,它看起来像 func::<T, U, ...>()
您的 load_file
函数应如下所示:
fn load_file() -> Vec<String> {
let file = BufReader::new(File::open("foo.txt").unwrap());
file.lines().map(|x| x.unwrap()).collect::<Vec<String>>()
}
您还可以通过将某些类型指定为占位符来允许某些类型推断继续 _
:
fn load_file() -> Vec<String> {
let file = BufReader::new(File::open("foo.txt").unwrap());
file.lines().map(|x| x.unwrap()).collect::<Vec<_>>()
}
事实上,您的问题不太明显。这不会编译(您的初始代码):
use std::fs::File;
use std::io::{BufRead, BufReader};
fn load_file() -> Vec<String> {
let file = BufReader::new(File::open("foo.txt").unwrap());
file.lines().map(|x| x.unwrap()).collect();
}
fn main() {
let data = load_file();
println!("DATA: {}", data[0]);
}
但是这样做:
use std::fs::File;
use std::io::{BufRead, BufReader};
fn load_file() -> Vec<String> {
let file = BufReader::new(File::open("foo.txt").unwrap());
file.lines().map(|x| x.unwrap()).collect()
}
fn main() {
let data = load_file();
println!("DATA: {}", data[0]);
}
你能注意到细微的差别吗?只是load_file()
.
最后一行的一个分号而已
Rust 中的类型推断足够强大,这里不需要注解。您的问题在于您忽略了 collect()
的结果!对于类型推断,分号的作用类似于 "barrier",因为它没有连接 collect()
的 return 类型和 load_file()
的 return 类型。但是,该错误消息有些误导;似乎这个阶段的类型检查 运行 早于 return 类型的检查(这将正确地失败,因为 ()
与 Vec<String>
不兼容)。
我有这个代码:
use std::fs::File;
use std::io::{BufRead, BufReader};
fn load_file() -> Vec<String> {
let file = BufReader::new(File::open("foo.txt").unwrap());
file.lines().map(|x| x.unwrap()).collect();
}
fn main() {
let data = load_file();
println!("DATA: {}", data[0]);
}
当我尝试编译它时,出现此错误:
error[E0283]: type annotations required: cannot resolve `_: std::iter::FromIterator<std::string::String>`
--> src/main.rs:6:38
|
6 | file.lines().map(|x| x.unwrap()).collect();
| ^^^^^^^
事实上,如果我这样改变load_file
函数,代码编译顺利:
fn load_file() -> Vec<String> {
let file = BufReader::new(File::open("foo.txt").unwrap());
let lines: Vec<String> = file.lines().map(|x| x.unwrap()).collect();
return lines;
}
此解决方案 "Rusty" 不够,因为不鼓励以 return 结束函数。
有没有办法将类型注释直接放入 file.lines().map(|x| x.unwrap()).collect();
语句中?
Iterator::collect
's signature 看起来像这样:
fn collect<B>(self) -> B
where
B: FromIterator<Self::Item>,
在你的情况下,你需要告诉它 B
是什么。要指定通用函数的类型,您可以使用称为 turbofish 的语法,它看起来像 func::<T, U, ...>()
您的 load_file
函数应如下所示:
fn load_file() -> Vec<String> {
let file = BufReader::new(File::open("foo.txt").unwrap());
file.lines().map(|x| x.unwrap()).collect::<Vec<String>>()
}
您还可以通过将某些类型指定为占位符来允许某些类型推断继续 _
:
fn load_file() -> Vec<String> {
let file = BufReader::new(File::open("foo.txt").unwrap());
file.lines().map(|x| x.unwrap()).collect::<Vec<_>>()
}
事实上,您的问题不太明显。这不会编译(您的初始代码):
use std::fs::File;
use std::io::{BufRead, BufReader};
fn load_file() -> Vec<String> {
let file = BufReader::new(File::open("foo.txt").unwrap());
file.lines().map(|x| x.unwrap()).collect();
}
fn main() {
let data = load_file();
println!("DATA: {}", data[0]);
}
但是这样做:
use std::fs::File;
use std::io::{BufRead, BufReader};
fn load_file() -> Vec<String> {
let file = BufReader::new(File::open("foo.txt").unwrap());
file.lines().map(|x| x.unwrap()).collect()
}
fn main() {
let data = load_file();
println!("DATA: {}", data[0]);
}
你能注意到细微的差别吗?只是load_file()
.
Rust 中的类型推断足够强大,这里不需要注解。您的问题在于您忽略了 collect()
的结果!对于类型推断,分号的作用类似于 "barrier",因为它没有连接 collect()
的 return 类型和 load_file()
的 return 类型。但是,该错误消息有些误导;似乎这个阶段的类型检查 运行 早于 return 类型的检查(这将正确地失败,因为 ()
与 Vec<String>
不兼容)。