首页 > 解决方案 > 如何使用自定义错误枚举修复不匹配的返回类型?

问题描述

我遇到了以下类型不匹配的错误。目前使用自定义错误枚举来保存来自各种板条箱的错误,如下error.rs所示,我正在尝试将它用于我的主函数的返回类型。如何转换错误以使类型不匹配?

错误信息

→ cargo build
   Compiling dphoto v0.1.0 (/home/drk/Documents/github/dphoto)
error[E0308]: mismatched types
  --> src/main.rs:10:1
   |
10 | #[actix_rt::main]
   | ^^^^^^^^^^^^^^^^^ expected enum `error::Error`, found struct `std::io::Error`
11 | async fn main() -> Result<()> {
   |                    ---------- expected `std::result::Result<(), error::Error>` because of return type
   |
   = note: expected type `std::result::Result<_, error::Error>`
              found type `std::result::Result<_, std::io::Error>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
error: could not compile `dphoto`.

构建信息和依赖项

→ rustc --version
rustc 1.39.0 (4560ea788 2019-11-04)

main.rs

use actix_files as fs;
use actix_web::{middleware, App, HttpServer};

mod api;
mod error;
mod resizer;
use api::{album, image};
use error::Result;

#[actix_rt::main]
async fn main() -> Result<()> {
    std::env::set_var("RUST_LOG", "actix_web=info");
    env_logger::init();

    HttpServer::new(|| {
        App::new()
            // enable logger
            .wrap(middleware::Logger::default())
            .service(
                // static files
                fs::Files::new("/static", "./static/").show_files_listing(),
            )
            .service(album)
            .service(image)
    })
    .bind("127.0.0.1:8080")?
    .start()
    .await
}

错误.rs

...

/// Common result type
pub type Result<T> = StdResult<T, Error>;

/// Common error type to hold errors from other crates
#[derive(Debug)]
pub enum Error {
    /// A `image` crate error
    Image(ImageError),
    /// A `std::io` crate error
    Io(IoError),
}

impl From<IoError> for Error {
    fn from(err: IoError) -> Error {
        Error::Io(err)
    }
}

...

标签: error-handlingrust

解决方案


由于以 开始HttpServer响应Result<(), io::error::Error>,因此需要将错误转换为自定义error::Error枚举。这可以通过使用?运算符然后将其再次包装在Ok(), so中来完成Ok(HttpServer ... .start().await?)

或者,一种更简洁的方式(imo)将错误转换为.map_err(Into::into).

.map_err()不需要用于.bind()调用,因为?操作员会转换错误。

#[actix_rt::main]
async fn main() -> Result<()> {
    std::env::set_var("RUST_LOG", "actix_web=info");
    env_logger::init();

    HttpServer::new(|| {
        App::new()
            // enable logger
            .wrap(middleware::Logger::default())
            .service(
                // static files
                fs::Files::new("/static", "./static/").show_files_listing(),
            )
            .service(album)
            .service(image)
    })
    .bind("127.0.0.1:8080")?
    .start()
    .await
    .map_err(Into::into)
}

推荐阅读