rust - Rust 中类似结构的重复代码删除

标签 rust

我有一个小项目,其中有一些类似的结构,其中 OrdPartialOrd 的实现是相同的。我是(主要)动态语言的新手,其中代码重复通常被认为是反模式,我想知道是否有办法避免重复此代码?或者,更一般地说,这是我应该在 Rust 中担心的事情吗?

例如:

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
}

有没有办法让ReservationEvent共享cmp的实现,这样代码就不需要重复了?

最佳答案

问题的核心是您首先在两个结构上复制相同的字段。通过将它们分解成一些单独的结构可以很容易地避免这种情况,例如:

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

然后你可以为其实现一次Ord & PartialOrd

impl Ord for TimeRange {
    // ...
}

impl PartialOrd for TimeRange {
    // ...
}

由于 TimeRange 现在是 Ord,您可以简单地派生 EventOrd 特征Reservation 因为这将委托(delegate)给 TimeRange 的实现。

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

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

此外,在您的具体示例中,您似乎首先按 start 排序,然后按持续时间排序。但是,如果 start-s 相等,则按持续时间进行比较相当于按 end 进行比较,因此您实际上是按 start 然后 进行排序>end,默认派生的 Ord 将为您提供该结果,而无需编写任何代码。

关于rust - Rust 中类似结构的重复代码删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61561612/

相关文章:

rust - 是否有u8个字节的类似char::escape_default的函数?

rust - 清除前设置剪刀矩形

rust - 如何将选项映射到字符串以进行格式化,同时提供 &'static str 作为默认值?

rust - cargo 的多个 Rust 源文件

string - 如何从 Rust 中的文字创建格式化字符串?

rust - 如何在 nom 中创建流解析器?

rust - 制作切片时所有权和借用如何运作?

arrays - 数组向量的内存布局是什么?

rust - 在已知不是 `let Some(var) = option;` 的情况下可以使用 `None` 语法吗?

rust - "panicked at ' 断言失败 : begin <= end"when using map