Как использовать объект черты в BinaryHeap?

У меня есть следующий упрощенный код:

use std::collections::BinaryHeap;
use std::rc::Rc;

struct JobId;
struct Coord;
struct TimeStep;

pub trait HasJob {
    fn id(&self) -> JobId;
    fn start(&self) -> Coord;
    fn end(&self) -> Coord;
    fn earliest_start(&self) -> TimeStep;
    fn latest_finish(&self) -> TimeStep;
}

type JobPtr = Rc<HasJob>;

// a concrete class that implements the above trait
// and other basic traits like Eq, Hash, Ord, etc
pub struct Job {}
// another class that implements the HasJob trait
pub struct JobPrime {}

fn main() {
    // this line raises a compiler error
    let heap: BinaryHeap<JobPtr> = BinaryHeap::with_capacity(10);
}

Основная идея заключается в использовании (уникальный) idдля заказа.

При инициализации кучи возникает следующая ошибка:

error[E0277]: the trait bound `HasJob: std::cmp::Ord` is not satisfied
  --> src/main.rs:24:36
   |
24 |     let heap: BinaryHeap<JobPtr> = BinaryHeap::with_capacity(10);
   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `HasJob`
   |
   = note: required because of the requirements on the impl of `std::cmp::Ord` for `std::rc::Rc<HasJob>`
   = note: required by `<std::collections::BinaryHeap<T>>::with_capacity`

Я только начал пробовать свои силы в Rust и имею опыт работы с OOP/C++/Java. Намерение состоит в том, чтобы использовать HasJob признак "интерфейс" и использование его для инициирования стирания / динамической отправки типов по сравнению с общими коллекциями / контейнерами - распространенный шаблон ООП.

Если я правильно понимаю, общий параметр BinaryHeap имеет ограничение, что конкретный тип, переданный ему, должен реализовать Ord черта характера. Попытка расширить исходную черту с необходимой чертой, как это...

pub trait HasJob: Ord + /*others*/

... нарушает гарантию безопасности объектов Rust и вызывает ошибку компилятора:

error[E0038]: the trait `HasJob` cannot be made into an object
  --> src/main.rs:16:22
   |
16 |     type JobPtr = Rc<HasJob>;
   |                      ^^^^^^ the trait `HasJob` cannot be made into an object
   |
   = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses

Как мне обойти вышеупомянутую проблему?

0 ответов

Другие вопросы по тегам