Дедупликация кода в ржавчине для подобных структур - PullRequest
1 голос
/ 02 мая 2020

У меня есть небольшие проекты, в которых есть несколько похожих структур, в которых реализация Ord и PartialOrd одинакова. Я новичок в работе с (в первую очередь) динамическими c языками, где дублирование кода часто считается антишаблоном, и мне интересно, есть ли способ избежать дублирования этого кода? Или, в более общем смысле, это то, о чем я должен беспокоиться в ржавчине?

Например:

struct Event {
  start: i32,
  end: i32,
  . . .
}

impl Ord for Event {
    fn cmp(&self, other: &Self) -> Ordering {
        let cmp = self.start.cmp(&other.start);
        if cmp == Ordering::Equal {
            (self.end - self.start).cmp(&(other.end - other.start))
        } else {
            cmp
        }
    }
}

impl PartialOrd for Event {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(&other)) }
}

struct Reservation {
    start: i32.
    end: i32,
    . . . 
}

impl Ord for Reservation {
    // same implementation as Event
}

impl PartialOrd for Reservation {
    // same implementation as Event
}

Есть ли способ, чтобы Reservation и Event совместно использовали реализацию cmp чтобы код не дублировался?

1 Ответ

2 голосов
/ 02 мая 2020

Суть вашей проблемы в том, что вы в первую очередь дублируете одни и те же поля в обеих структурах. Этого легко избежать, выделив их в какую-то отдельную структуру, например:

#[derive(Eq, PartialEq)]
struct TimeRange {
    start: i32,
    end: i32,
}

Тогда вы можете реализовать Ord & PartialOrd для него один раз.

impl Ord for TimeRange {
    // ...
}

impl PartialOrd for TimeRange {
    // ...
}

Так как TimeRange теперь Ord, вы можете просто получить черту Ord для Event и Reservation, поскольку она будет делегироваться TimeRange impl.

#[derive(Eq, PartialEq, Ord, PartialOrd)]
struct Event {
    range: TimeRange,
}

#[derive(Eq, PartialEq, Ord, PartialOrd)]
struct Reservation {
    range: TimeRange,
}

Кроме того, в Ваш конкретный пример c, который вы, кажется, сначала сортируете по start, а затем по продолжительности. Но если start -s равны, то сравнение по длительности эквивалентно сравнению по end, и, таким образом, вы эффективно сортируете по start, тогда end, который по умолчанию Ord даст вам без необходимости напишите код NAY.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...