【问题标题】:Why is the failure::Fail trait bound not satisfied by my Result type alias?为什么我的 Result 类型别名不满足 failure::Fail 特征绑定?
【发布时间】:2019-01-05 08:33:37
【问题描述】:

我正在尝试实现 "simple event hooks in Rust" 所展示的事件挂钩,同时还使用失败箱的 Error + ErrorKind 模式。

这是我的代码的精简版:

#[macro_use]
extern crate failure;

use failure::{Backtrace, Context, Error, Fail};
use std::fmt;

#[derive(Debug)]
pub struct PortalError {
    inner: Context<PortalErrorKind>,
}

impl Fail for PortalError {
    fn cause(&self) -> Option<&Fail> {
        self.inner.cause()
    }

    fn backtrace(&self) -> Option<&Backtrace> {
        self.inner.backtrace()
    }
}

impl fmt::Display for PortalError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&self.inner, f)
    }
}

#[derive(Copy, Clone, PartialEq, Debug, Fail)]
pub enum PortalErrorKind {
    #[fail(display = "Unknown Error")]
    Unknown,
}

//----------------------------------------------------------

pub type PortalResult<T> = Result<PortalError, T>;
pub trait Portal {
    fn get_something(&self) -> PortalResult<Vec<u32>>;
}

//----------------------------------------------------------

pub trait FeedApi<'a> {
    type T: FeedApi<'a>;

    fn new<P: Portal + 'a>(portal: P) -> Result<Self::T, Error>;
}

//----------------------------------------------------------

pub struct Feedly<'a> {
    portal: Box<Portal + 'a>,
}

impl<'a> FeedApi<'a> for Feedly<'a> {
    type T = Feedly<'a>;

    fn new<P: Portal + 'a>(portal: P) -> Result<Self::T, Error> {
        Ok(Feedly {
            portal: Box::new(portal),
        })
    }
}

impl<'a> Feedly<'a> {
    pub fn demo_function(&self) -> Result<(), Error> {
        let _ = self.portal.get_something().context(PortalErrorKind::Unknown)?;
        Ok(())
    }
}

fn main() {
    println!("Hello, world!");
}
[dependencies]
failure = "0.1.1"

在“Feedly”的方法中,我想使用门户:

self.portal.get_something().context(PortalErrorKind::Unknown)?

但我收到以下错误:

error[E0599]: no method named `context` found for type `std::result::Result<PortalError, std::vec::Vec<u32>>` in the current scope
  --> src/main.rs:67:45
   |
67 |         let _ = self.portal.get_something().context(PortalErrorKind::Unknown)?;
   |                                             ^^^^^^^
   |
   = note: the method `context` exists but the following trait bounds were not satisfied:
           `std::result::Result<PortalError, std::vec::Vec<u32>> : failure::Fail`
           `&std::result::Result<PortalError, std::vec::Vec<u32>> : failure::Fail`
           `&mut std::result::Result<PortalError, std::vec::Vec<u32>> : failure::Fail`

查看文档,failure::Fail trait 有一个绑定 'static。并且方法context 有一个绑定Self: Sized

我不确定这里不满足哪个特征。装箱的Portal既不是Sized也不是'static,但是返回的结果应该是吧?

这是我第一次在 Rust 中处理盒子和生命周期。

【问题讨论】:

    标签: rust traits lifetime


    【解决方案1】:
    pub type PortalResult<T> = Result<PortalError, T>;
    

    Result 有两个类型参数:成功类型和错误类型。你已经调换了它们;你想要的:

    pub type PortalResult<T> = Result<T, PortalError>;
    

    【讨论】:

    • 天啊。你是对的。没想到错误就这么简单。编译器引导我走向完全不同的方向。谢谢,对噪音感到抱歉。希望至少其他人可以从我的愚蠢错误中吸取教训:D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-10
    • 2019-09-12
    • 2021-03-30
    • 1970-01-01
    • 2021-03-16
    • 2022-11-30
    • 1970-01-01
    相关资源
    最近更新 更多