Rust 为外来类型实现外来特性

Rust 为外来类型实现外来特性,rust,Rust,因此,我认为有理由禁止孤立的trait实现,因为考虑到前向兼容性(防止在库中添加进一步的trait实现破坏使用类型trait的地方),这可能会使编译变得更加困难。但我想知道Rust社区认为哪种解决方案是最理想的: (以防万一,这还不够背景:我正试图使用with'sDateTime。所以我想实现rusqlite的FromSql和ToSql特性,用于DateTime,但这显然不像我想象的那么容易——我现在刚开始使用Rust。) Fork rusqlite并实现trait。(我觉得这不是最好的方法,

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

(以防万一,这还不够背景:我正试图使用with's
DateTime
。所以我想实现rusqlite的
FromSql
ToSql
特性,用于
DateTime
,但这显然不像我想象的那么容易——我现在刚开始使用Rust。)

  • Fork rusqlite并实现trait。(我觉得这不是最好的方法,因为可能只有我需要这个特性的实现,所以我可能最终不得不让我自己的fork保持最新。另外,我无法实现这些特性,因为有些复杂的泛型,我还没有完全理解。)
  • 实现我自己的
    DateTime
    struct(可能是最好的解决方法,但我觉得这只是一些不必要的工作的复制)
  • 不知何故,“复制”了
    DateTime
    特性,给它一个别名,并为我的别名类型实现了
    FromSql
    ToSql
    特性(但是我认为这也不是小事,当我尝试它时,我无法让它工作,因为它仍然被视为外部类型)

我希望有人能向我解释如何最好地解决这个问题,根据我纯粹的OOP经验,我只希望能够继承
DateTime
并实现接口,但(出于合理的原因)这不是在Rust中实现的方式…

最简单的方法是使用新类型模式:

extern crate a;
extern crate b;

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

pub struct MySomeStruct(SomeStruct);

impl SomeTrait for MySomeStruct {
    ...
}
在这里,您围绕外部结构创建了一个包装器,因为这个包装器是属于您的板条箱的一种完全不同的类型,您可以自由地为它实现
a::SomeTrait
。这与您的第二点类似,只是您完全不需要从头开始重新实现该类型


当然,您不能在
MySomeStruct
上调用
SomeStruct
的所有方法。您必须转发所需的所有方法,或者在不再需要trait实现时打开内部值,或者您可以为MySomeStruct{type Target=SomeStruct;…},但后者被视为反模式。

我不确定最惯用的是什么,但看起来最好的方法是使用newtype模式,这是一个只有一个字段的元组结构。这将创建一个不同于旧类型的新类型,您可以实现该新类型的特征。要使用trait方法,您需要将其包装到newtype中,但要使用普通方法,您将使用普通结构而不使用newtype包装器

struct MyType(TheirType);

impl TheTrait for MyType {
    ....
}

fn main() {
    let a = TheirType::new(....);
    a.method_on_their_type();
    let b = MyType(TheirType::new(....));
    b.method_on_the_trait();
}

为什么它被视为反模式?@Folling请查看: