【问题标题】:How to hide trait implementation in Rust如何在 Rust 中隐藏 trait 实现
【发布时间】:2023-03-06 11:48:01
【问题描述】:

我有一个项目有自己的错误类型,它暴露在 crate 之外。让我们称之为MyErrorType。项目本身在内部依赖于另一个具有自己错误类型的 crate。让我们称之为ForeignErrorType

为了简化代码并使其更具可读性,我创建了以下From trait 的实现:

impl From<ForeignErrorType> for MyErrorType {
   ...
}

这允许在处理外部错误类型时使用问号运算符?,而无需就地转换它们。

问题是提到的 trait 实现暴露在我的 crate 之外。我不希望我的 crate 的用户意外依赖从 ForeignErrorTypeMyErrorType 的转换可能性。

到目前为止我所做的尝试: 已将提到的 trait 实现放入具有 pub(crate) 可见性的模块中。这令人惊讶地隐藏了此类模块中定义的所有structs,但暴露了特征实现。

  • 有没有办法让我的 From 实现保持私有而不将其暴露在 crate 之外?
  • 可能我正试图以一种非惯用的方式来获得错误处理的好处。如果这是真的,那么在不暴露外部错误类型的情况下使用 ? 运算符的正确方法是什么?

【问题讨论】:

  • 出于好奇,您为什么不希望 API 的使用者能够使用 From 实现?更简单的方法可能是定义一个名为transform_errpub(crate) 函数或其他东西,并且每当返回Result&lt;_, ForeignError&gt; 时,您手动调用map_err。确定是更多的击键但完成了工作?
  • 您为什么不希望您的 API 的使用者能够使用 From 实现? 假设将来某个时候我想在内部使用另一个 crate,如果以前使用的 crate 没有任何部分暴露在外面,我只需要调整内部代码。否则,这是对 API 的重大更改。 一个更简单的方法可能是......我认为它是一个后备选项。但是有一个简单的? 而不是一个额外的函数,可读性会更好
  • 我想最简单的方法是创建一个暴露的包装结构,它实际上除了错误之外没有实现任何东西。

标签: rust error-handling


【解决方案1】:

有没有办法让我的 From 实现保持私有而不将其暴露在 crate 之外?

没有。特征实现没有范围。

在这种情况下,您可以做的是编写一个与您的 From 实现具有相同内容的函数,并在 ? 之前使用 Result::map_err 应用它。

pub(crate) fn foreign_err(e: ForeignErrorType) -> MyErrorType {
    todo!()
}

...

let foo = their_function().map_err(foreign_err)?;

这必须在每次使用 ? 时完成,但是没有办法进行范围为 crate 或模块的隐式转换,所以这是你可以拥有的最好的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-19
    • 2023-03-26
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    相关资源
    最近更新 更多