Rust:fn foo()-> Result <()>抛出“期望的2个类型参数”

时间:2018-12-02 21:07:35

标签: error-handling rust

为什么编译这部分Rust代码时不允许Result<()>? Rust版本之间是否有重大变化?

fn run() -> Result<()> {
    let (tx, rx) = channel();

    thread::spawn(move || {
        do_things_with_tx(&exit_tx);
    });

    match exit_rx.recv() {
        Ok(result) => if let Err(reason) = result {
            return Err(reason);
        },
        Err(e) => {
            return Err(e.into());
        },
    }

    Ok(())
}

编译器说:

error[E0107]: wrong number of type arguments: expected 2, found 1
    --> src/main.rs:1000:18
     |
1000 | fn run_wifi() -> Result<()> {
     |                  ^^^^^^^^^^ expected 2 type arguments

当我将返回类型调整为Result<(), Err>时,它说:

error[E0107]: wrong number of type arguments: expected 2, found 0
    --> src/main.rs:1000:29
     |
1000 | fn run() -> Result<(), Err> {
     |                        ^^^ expected 2 type arguments

这来自Semaphore。早晨将跟踪可重复的MVCE。

2 个答案:

答案 0 :(得分:8)

Result的定义始终是以下内容:

pub enum Result<T, E> {
    Ok(T),
    Err(E),
}

这个定义甚至在the Rust Programming language中也有介绍,以表明它的简单性。作为 OK 结果和 error 结果的通用和类型,它总是期望两个类型参数,并且编译器会抱怨它无法推断它们或类型参数列表没有预期的长度。

另一方面,可能会发现许多库和相应的文档显示了带有单个类型实参的Result,如Result<()>中所示。有什么作用?

这仍然不是魔术。按照惯例,库在板条箱或模块级别为结果类型创建类型别名。这样效果很好,因为通常会产生相同的本地创建类型的错误。

pub type Result<T> = Result<T, Error>;

事实上,很普遍,当使用error_chain!宏时,许多错误类型辅助工具之一的工具箱error-chain会自动创建此定义。 因此,如果您在使用error-chainsuch as wifi-connect)的项目中,或者正在使用可能会或可能不会使用error-chain的库中,则应该假定提到了{{1 }}是特定于域的Result<T>的本地类型别名。如有疑问,请在生成的文档页面中单击该类型,将您带到具体定义(在本例中为别名)。

答案 1 :(得分:1)

来自The Rust Programming Language部分The ? Operator Can Only Be Used in Functions That Return Result

use std::error::Error;
use std::fs::File;

fn main() -> Result<(), Box<dyn Error>> {
    let f = File::open("hello.txt")?;

    Ok(())
}