当前位置: 首页 > 知识库问答 >
问题:

如何实现`From

郑嘉年
2023-03-14

我正在编写一个新的板条箱,我希望它能与一个特征的任何实现(在另一个板条箱中定义)一起使用。该特性看起来如下所示:

pub trait Trait {
   type Error;
   ...
}

我有自己的error类型,但有时我只想不加修改地转发底层错误。我的本能是这样定义一个类型:

pub enum Error<T: Trait> {
    TraitError(T::Error),
    ...
}
impl<T: Trait> From<T::Error> for Error<T> {
    fn from(e: T::Error) -> Self { Self::TraitError(e) }
}

我看过其他几个crate,它们似乎通过使其error(或等价物)泛型于错误类型本身,而不是特性实现来处理这一问题。当然,这是可行的,但是:

  • 除非我们有了固有的关联类型,否则它要冗长得多。我的t实际上实现了多个特性,每个特性都有自己的error类型,因此我现在必须返回result<...、error< ::error、 ::error> 等类型;
  • 可以说它的表达能力较差(因为与trait的关系丢失了)。

使我的error泛型于单个类型是当前最好的(最惯用的)选择吗?

共有1个答案

轩辕奕
2023-03-14

与其为error枚举实现,不如考虑使用result::map_err来指定返回哪个变量。这甚至适用于使用关联类型的类型上的泛型枚举,例如:

trait TraitA {
  type Error;
  fn do_stuff(&self) -> Result<(), Self::Error>;
}

trait TraitB {
  type Error;
  fn do_other_stuff(&self) -> Result<(), Self::Error>;
}

enum Error<T: TraitA + TraitB> {
  DoStuff(<T as TraitA>::Error),
  DoOtherStuff(<T as TraitB>::Error),
}

fn my_function<T: TraitA + TraitB>(t: T) -> Result<(), Error<T>> {
  t.do_stuff().map_err(Error::DoStuff)?;
  t.do_other_stuff().map_err(Error::DoOtherStuff)?;
  Ok(())
}

在操场上

这里重要的一点是error没有from实现(除了覆盖的实现),并且使用map_err指定变体。这是因为error::dostuff在传递给map_err时可以被解释为fn( ::error)->error error::dootherstuff也发生同样的情况。

无论error有多少变体,无论它们是否是同一类型,这种方法都是可伸缩的。对于阅读函数的人来说,这也可能更清楚,因为他们不需要检查from实现,也不需要检查从函数中转换的类型出现在哪里,就可以知道某个错误来自某个地方。

 类似资料:
  • 问题内容: 我在同一HTML页面上同时使用了javascript和jquery代码。由于某种原因,jQuery库正在阻止我的本机javascript代码正常工作。 我找到了此页面:jQuery No Conflict,它表明您可以使用jquery.noConflict将$释放回javascript。但是,我不确定该怎么做? 具体来说,我不确定如何正确执行此操作?Jquery代码在哪里,JS代码在哪

  • 问题内容: 我已经开发Web应用程序已有一段时间了,但是最近使用Comet服务器端推送技术对其进行了介绍,而我对该技术的理解还很不成熟。虽然链接http://www.zeitoun.net/articles/comet_and_php/start提供了两个使用PHP中无限循环的简单示例实现,但我想进一步了解上述方法的用途以及是否适合生产。专用彗星服务器如Meteor(http://meteorse

  • 异步读取 新建一个  ExcelModelListener 监听类出来,并且 继承 AnalysisEventListener 类 package com.zh.oukele.listener; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListen

  • myapp e/AndroidRuntime:致命异常:main java.lang.ClassCastException:com.domain.myapp.MainActivity@422FB8F0必须实现OnFragmentInteractionListener 我找不到任何地方如何实现这个OnFragmentInteractionListener??甚至在android sdk文档中也找不到

  • 问题内容: 我想实施一个。 我不想只使用,因为我必须实现大量的方法。 可以避免吗? 更具体的,我怎么能流,以及例如: 问题答案: JDK的标准实现是内部类,您不能直接实例化它。 相反,你可以使用,以及各种1,2种静态工厂方法来创建默认实现的实例。 使用分离器可能是最强大的方法,因为它可以让您懒惰地提供对象,同时如果您的源可以分为多个块,则还可以实现有效的并行化。 此外,如果需要实现自己的 有状态中

  • 问题内容: IObjectTest是具有单个布尔测试(对象o)方法的接口 FilteringIterator是Iterator的实现,该实现使用另一个Iterator和一个IObjectTest实例初始化:new FilteringIterator(myIterator,myTest)。然后,您的FilteringIterator将允许在“ myIterator”上进行迭代,但是会跳过所有未通过“