error-handling - 如何使用自定义错误枚举来修复不匹配的返回类型?

标签 error-handling rust

我遇到了类型不匹配的以下错误。当前正在使用自定义的Error枚举来保存来自各种 crate 的错误,如下面的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)



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
}

错误

...

/// 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)
    }
}

...

最佳答案

由于启动HttpServer会以Result<(), io::error::Error>进行响应,因此需要将错误转换为自定义error::Error枚举。这可以通过使用?运算符,然后再次将其包装在Ok()中来完成,即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)
}

关于error-handling - 如何使用自定义错误枚举来修复不匹配的返回类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59297985/

相关文章:

java - 为什么我的switch语句生成IOException

rust - 我可以创建一个编译错误来检查一个特征是否有另一个特征作为超特征吗?

rust - Option::map(FnOnce) 似乎不接受 FnOnce ...?

rust - 通过变量访问结构字段

rust - 如何从移动到结构中的 Vec 中检索项目?

scala - 类型删除 : Rust vs Scala

c - 数组下标的无效类型 int[int]

java - JAX-RS 客户端可以抛出自定义异常类型吗?

vb.net - 将文本写入VB中的文件时出现格式异常错误

ruby-on-rails - 为什么在某些情况下 Rails 应用返回 406 而不是 404?