如何在迭代器的 collect 语句中放置类型注释? [英] How to put a type annotation in an iterator's collect statement?

查看:30
本文介绍了如何在迭代器的 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]);}

当我尝试编译它时,出现此错误:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆