在创建使用try运算符的闭包时,如何修复错误“需要输入注释”?

问题描述 投票:2回答:3
use std::fs::File;

fn main() {
    let tmp = "tmp.zip";

    let save_to_tmp_file = || {
        let mut tmp_zip = File::create(tmp)?;
        Ok(())
    };

    save_to_tmp_file();
}

(Qazxswpoi)

构建错误:

playground
error-handling rust closures type-inference
3个回答
3
投票

您必须指定返回类型:

error[E0282]: type annotations needed
 --> src/main.rs:7:27
  |
6 |     let save_to_tmp_file = || {
  |         ---------------- consider giving `save_to_tmp_file` a type
7 |         let mut tmp_zip = File::create(tmp)?;
  |                           ^^^^^^^^^^^^^^^^^^ cannot infer type for `_`

关闭有一个问题。你不能命名闭包的类型;你可以尝试将它减少到use std::fs::File; use std::io; fn main() { let tmp = "tmp.zip"; let save_to_tmp_file = || -> Result<(), io::Error> { let mut tmp_zip = File::create(tmp)?; Ok(()) }; save_to_tmp_file(); } / FnOnce,但你仍然必须给它返回类型。

为了克服你的情况,你可以指定一个FnMut作为Result

return type for your main function

2
投票

编译器无法推断闭包的返回类型。

最后返回use std::io; use std::fs::File; fn main() -> Result<(), io::Error> { let tmp = "tmp.zip"; let mut tmp_zip = File::create(tmp)?; Ok(()) } 让编译器推断出成功结果的类型是什么,而不是错误类型是什么。 Ok(())运算符的返回类型确实包含完整的具体类型,但保证这种类型可以转换为周围函数返回的任何类型。因此,我们需要修复该返回类型,以便可以推断出所有省略的类型注释。

?通过删除Tyfingr's answer来解决问题,因此闭包的返回类型与?的返回类型相同。

File::create(tmp)在闭包上添加了一个注释,以便编译器不需要推断类型。

第三个修复是将类型注释放在返回值上:

hellow's answer

这类似于hellow的编辑,将类型放在let save_to_tmp_file = || { let mut tmp_zip = File::create(tmp)?; Ok(()) }; let result: Result<_, io::Error> = save_to_tmp_file(); 的返回值中。

通常,您应该使用main(),如果不这样做,编译器会发出警告。处理错误时,您很可能无意中为编译器提供了足够的类型信息,而这些信息都不是必需的。


1
投票

Rust是一种富有表现力的语言,所以你可以返回Result并且它工作正常:

Result

或者只写:

use std::fs::File;

fn main() {
    let tmp = "tmp.zip";

    let save_to_tmp_file = || {
        File::create(tmp)
    };

    save_to_tmp_file().expect("Can't create a tmp file");
}
© www.soinside.com 2019 - 2024. All rights reserved.