无论如何混合::结果与 std::io::Result

Ziz*_*Tai 7 rust

谁能帮我理解为什么这段代码编译得很好:

use actix_web::{App, HttpServer};
use anyhow::Result;

mod error;

#[actix_rt::main]
async fn main() -> Result<()> {
    HttpServer::new(|| App::new())
        .bind("127.0.0.1:8080")?
        .run()
        .await?;

    Ok(())
}
Run Code Online (Sandbox Code Playgroud)

虽然这不编译:

use actix_web::{App, HttpServer};
use anyhow::Result;

mod error;

#[actix_rt::main]
async fn main() -> Result<()> {
    HttpServer::new(|| App::new())
        .bind("127.0.0.1:8080")?
        .run()
        .await
}

Run Code Online (Sandbox Code Playgroud)

有错误:

error[E0308]: mismatched types
 --> src/main.rs:6:1
  |
6 | #[actix_rt::main]
  | ^^^^^^^^^^^^^^^^^ expected struct `anyhow::Error`, found struct `std::io::Error`
7 | async fn main() -> Result<()> {
  |                    ---------- expected `std::result::Result<(), anyhow::Error>` because of return type
  |
  = note: expected enum `std::result::Result<_, anyhow::Error>`
             found enum `std::result::Result<_, std::io::Error>`
  = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
Run Code Online (Sandbox Code Playgroud)

这两个例子有什么根本区别?

Cal*_*ngh 15

您可以使用与以下内容相同的转换anyhow

use actix_web::{App, HttpServer};
use anyhow::Result;

#[actix_rt::main]
async fn main() -> Result<()> {
    HttpServer::new(|| App::new())
        .bind("127.0.0.1:8080")?
        .run()
        .await.map_err(anyhow::Error::from)
}
Run Code Online (Sandbox Code Playgroud)


Ben*_*ick 9

的问题是,第二个例子是返回Result<(), std::io::Error>其由启动服务器返回,而第二个被返回Result<(), anyhow::Error>的形式Ok(())

第一个示例起作用的原因是?运算符(或try!宏)执行从返回的任何错误到函数返回类型的错误的转换。

文档

在 Err 变体的情况下,它检索内部错误。尝试!然后使用 From 执行转换。这提供了特殊错误和更一般错误之间的自动转换。


pig*_*nds 5

anyhow::Error 实现From<std::error::Error>,但它们不是同一件事。

在第一个中,?正在获取std::error::Errorfromrun().await并进行调用anyhow::Error::from。第二个则不然。

将方法的返回类型更改为

Result<(), std::error::Error>
Run Code Online (Sandbox Code Playgroud)

解决了这个问题。