为什么我返回错误类型时不进行隐式转换?

时间:2019-09-18 14:57:23

标签: error-handling rust type-conversion

以下代码无法编译

// winservice.rs

#[macro_use] extern crate err_derive;
extern crate windows_service;

use windows_service::service_manager::{ServiceManager, ServiceManagerAccess};

#[derive(Debug, Error)]
pub enum WinServiceError {
    #[error(display = "could not query windows services api")]
    WinApiError(windows_service::Error),
}

impl From<windows_service::Error> for WinServiceError {
    fn from(error: windows_service::Error) -> Self {
        WinServiceError::WinApiError(error)
    }
}

fn get_manager(request_access: ServiceManagerAccess) -> Result<ServiceManager, WinServiceError> {
    ServiceManager::local_computer(None::<&str>, request_access)
}

pub fn main() {
    // get_manager();
}

我遇到了错误

error[E0308]: mismatched types
   --> src/winservice.rs:186:5
    |
185 | fn get_manager(request_access: ServiceManagerAccess) -> Result<ServiceManager, Error> {
    |                                                         ----------------------------- expected `std::result::Result<windows_service::service_manager::ServiceManager, winservice::Error>` because of return type
186 |     ServiceManager::local_computer(None::<&str>, request_access)
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `winservice::Error`, found enum `windows_service::Error`
    |
    = note: expected type `std::result::Result<_, winservice::Error>`
               found type `std::result::Result<_, windows_service::Error>`

为什么Rust编译器auto converting the return typewindows_service::Errorwinservice::Error

1 个答案:

答案 0 :(得分:0)

由于@Shepmaster的帮助,我得以解决该错误。

我没有意识到我是直接返回结果对象。我必须打开结果对象才能进行转换。

以下代码尝试将Result<_, windows_services::Error>类型的值返回为Result<_, WinServiceError>

fn get_manager(request_access: ServiceManagerAccess) -> Result<ServiceManager, WinServiceError> {
    ServiceManager::local_computer(None::<&str>, request_access)
}

但是以下代码有效,因为我们现在正在创建具有正确签名的新Result对象,并且rust编译器在创建新对象时执行错误类型之间的转换。

fn get_manager(request_access: ServiceManagerAccess) -> Result<ServiceManager, WinServiceError> {
    Ok(ServiceManager::local_computer(None::<&str>, request_access)?)
}