rust 我如何为另一个特质派生一个特质?

dl5txlt9  于 2023-04-12  发布在  其他
关注(0)|答案(2)|浏览(147)

我有一个包含trait对象成员的结构体,如下所示:

trait Contract {}

#[derive(Debug)]
struct Foo {
    x: Box<Contract>,
}

我想让这个结构体派生出Debug,但是编译器不喜欢它:

error[E0277]: `Contract + 'static` doesn't implement `std::fmt::Debug`
 --> src/main.rs:5:5
  |
5 |     x: Box<Contract>,
  |     ^^^^^^^^^^^^^^^^ `Contract + 'static` cannot be formatted using `:?`; add `#[derive(Debug)]` or manually implement `std::fmt::Debug`
  |
  = help: the trait `std::fmt::Debug` is not implemented for `Contract + 'static`
  = note: required because of the requirements on the impl of `std::fmt::Debug` for `std::boxed::Box<Contract + 'static>`
  = note: required because of the requirements on the impl of `std::fmt::Debug` for `&std::boxed::Box<Contract + 'static>`
  = note: required for the cast to the object type `std::fmt::Debug`

我不知道该如何解决这个问题。我理解为什么编译器不能为trait实现Debug,因为它不能告诉什么类型将实现它,但同样的原因也是我不为trait手动实现它的原因(甚至不确定这是否可能)。
什么是获得我想要的行为的好方法?

c3frrgcw

c3frrgcw1#

Traits不能使用#[derive()]属性;你需要手动实现它:

trait Contract {}

impl std::fmt::Debug for Contract {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}", "derp")
    }
}

由于trait对象会丢失类型信息(类型擦除),因此您可以使用Contract实现的函数,但您无法访问Debug的底层类型或其特定实现。
但是,如果你让Contract依赖于Debug trait,确保它的所有实现者也必须实现Debug

trait Contract: std::fmt::Debug {}

您将能够为foo实现#[derive(Debug)],而无需手动为Contract实现Debug

bejyjqdl

bejyjqdl2#

根据Rust 2021,你可以像这样为另一个trait实现trait:

trait Contract: Debug {}

#[derive(Debug)]
struct Foo {
    x: Box<Contract>,
}

相关问题