为外来类型实现外来特征

evo*_*pid 8 rust

因此,我认为出于向前兼容性考虑(以防止在库中添加进一步的 trait 实现破坏使用类型特征的地方),有理由禁止孤儿 trait 实现,并且可能使编译变得更加困难。但我想知道 Rust 社区认为哪种解决方法是最理想的:

(以防万一,这是不够的背景:我试图使用rusqlite时辰DateTime所以我想实现rusqlite的。FromSqlToSql的性状DateTime<UTC>,但是这显然不是那么容易,因为我觉得这一定是-我刚开始目前使用 Rust。)

  • Fork rusqlite 并实现 trait。(我有点觉得这不是最好的方法,因为也许只有我需要在那里实现这个特征,所以我最终可能不得不让我自己的叉子保持最新状态。我也无法实现特性,因为有一些复杂的泛型我还不完全理解。
  • 实现我自己的DateTime结构(可能是最好的解决方法,但我觉得这只是一些不必要的工作复制)。
  • 不知何故“复制”DateTime<UTC>特征并给它一个别名并为我的别名类型实现FromSqlToSql特征(但是我认为这也不是微不足道的,当我尝试它时我无法让它工作,因为它仍然被视为外部类型)。

我希望有人可以向我解释如何最好地解决这个问题,从我纯 OOP 经验来看,我只想能够继承DateTime和实现接口,但是(出于正当理由)这不是在 Rust 中完成的方式......

Vla*_*eev 11

最简单的方法是使用 newtype 模式:

extern crate a;
extern crate b;

use a::SomeTrait;
use b::SomeStruct;

pub struct MySomeStruct(SomeStruct);

impl SomeTrait for MySomeStruct {
    ...
}
Run Code Online (Sandbox Code Playgroud)

在这里,您围绕外部结构创建一个包装器,并且由于此包装器是属于您的 crate 的完全不同的类型,因此您可以自由地实现a::SomeTrait它。这类似于您的第二点,除了您绝对不需要从头开始重新实现该类型。

自然,您将无法调用SomeStructon 的所有方法MySomeStruct。您必须转发您想要的所有方法,或者当您不再需要其特征实现时解开内部值,或者您可以impl Deref for MySomeStruct { type Target = SomeStruct; ... },但后者被视为反模式。

  • @Folling 看看这个:/sf/ask/3156061681/ (2认同)