如何在迭代器的 collect 语句中放置类型注释? [英] How to put a type annotation in an iterator's collect statement?
问题描述
我有这个代码:
使用 std::fs::File;使用 std::io::{BufRead, BufReader};fn load_file() ->Vec{让文件 = BufReader::new(File::open("foo.txt").unwrap());file.lines().map(|x| x.unwrap()).collect();}fn 主(){让数据 = load_file();println!("数据:{}",数据[0]);}
当我尝试编译它时,出现此错误:
error[E0283]:需要类型注释:无法解析`_: 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{让文件 = BufReader::new(File::open("foo.txt").unwrap());让行:Vec= file.lines().map(|x| x.unwrap()).collect();返回线;}
这个解决方案不够生锈",因为不鼓励以返回结束函数.
有没有办法把类型注解直接放到file.lines().map(|x| x.unwrap()).collect();
语句中?
实际上,您的问题不太明显.这不会编译(您的初始代码段):
使用 std::fs::File;使用 std::io::{BufRead, BufReader};fn load_file() ->Vec{让文件 = BufReader::new(File::open("foo.txt").unwrap());file.lines().map(|x| x.unwrap()).collect();}fn 主(){让数据 = load_file();println!("数据:{}",数据[0]);}
但这确实是:
使用 std::fs::File;使用 std::io::{BufRead, BufReader};fn load_file() ->Vec{让文件 = BufReader::new(File::open("foo.txt").unwrap());file.lines().map(|x| x.unwrap()).collect()}fn 主(){让数据 = load_file();println!("数据:{}",数据[0]);}
你能注意到细微的差别吗?它只是 load_file()
最后一行的一个分号.
Rust 中的类型推断足够强大,不需要在这里添加注释.您的问题在于您忽略了 collect()
的结果!分号就像是类型推断的屏障",因为它没有连接 collect()
的返回类型和 load_file()
的返回类型.然而,错误信息有些误导;似乎这个阶段的类型检查早于检查返回类型(这将正确地失败,因为 ()
与 Vec
不兼容).>
I have this code:
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]);
}
When I try to compile it, I get this error:
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();
| ^^^^^^^
In fact, if I change the load_file
function in this way, the code compiles smoothly:
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;
}
This solution is not "Rusty" enough because ending a function with a return is not encouraged.
Is there a way to put the type annotation directly into the file.lines().map(|x| x.unwrap()).collect();
statement?
In fact your problem was slightly less noticeable. This does not compile (your initial piece of code):
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]);
}
But this does:
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]);
}
Can you notice the subtle difference? It's just a semicolon in the last line of load_file()
.
Type inference in Rust is strong enough not to need an annotation here. Your problem was in that you was ignoring the result of collect()
! The semicolon acted like a "barrier" for the type inference, because with it collect()
's return type and load_file()
's return type are not connected. The error message is somewhat misleading, however; it seems that this phase of type checking ran earlier than the check for return types (which would rightly fail because ()
is not compatible with Vec<String>
).
这篇关于如何在迭代器的 collect 语句中放置类型注释?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!