Как получить черту для другой черты? - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть структура, которая содержит элемент объекта черты, подобный этому:

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`

Я не совсем уверен, как это исправить. Я понимаю, почему компилятор не может реализовать Debug для признака, поскольку он не может сказать, какие типы будут его реализовывать, но та же самая причина состоит в том, что мешает мне реализовать это вручную для признака (даже не уверен, возможно ли это вообще) ).

Какой будет хороший подход для получения желаемого поведения?

1 Ответ

0 голосов
/ 26 апреля 2018

Черты не могут использовать атрибут #[derive()]; вам нужно реализовать это вручную:

trait Contract {}

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

Поскольку объекты признаков теряют информацию о типе ( стирание типов ), вы можете использовать функции, реализованные Contract, но у вас не будет доступа к базовым типам или их конкретным реализациям * 1008. *.

Если, однако, вы делаете Contract зависимым от черты Debug, гарантируя, что все его разработчики также должны реализовать Debug:

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

Вы сможете #[derive(Debug)] для foo без необходимости вручную вводить Debug для Contract.

...