Rust BinaryHeap是否仅将PartialEq用于排序顺序,还是用于真正的等价性?

Rust BinaryHeap是否仅将PartialEq用于排序顺序,还是用于真正的等价性?,rust,Rust,我想使用自己的排序条件将MyStruct存储在BinaryHeap中。我必须实现Ord和PartialEq,但是堆是否只将PartialEq用于排序,还是还将使用它来确定MyStruct实例1和MyStruct实例2在逻辑上是同一个对象,因此可以在我背后晃动东西 例如,它是否可以决定“下一步是inst2,但我已经在一些缓存中有inst1,所以我将再次返回它” 我的实例是非常不同的对象-它们只是具有相同的排序键 我有这个密码。这是不是因为我的Eq实现只比较了我想要排序的内容?我想把这些对象放在一个

我想使用自己的排序条件将
MyStruct
存储在
BinaryHeap
中。我必须实现
Ord
PartialEq
,但是堆是否只将
PartialEq
用于排序,还是还将使用它来确定
MyStruct
实例1和
MyStruct
实例2在逻辑上是同一个对象,因此可以在我背后晃动东西

例如,它是否可以决定“下一步是
inst2
,但我已经在一些缓存中有
inst1
,所以我将再次返回它”

我的实例是非常不同的对象-它们只是具有相同的排序键

我有这个密码。这是不是因为我的
Eq
实现只比较了我想要排序的内容?我想把这些对象放在一个
二进制堆中
。在我当前的代码中,我将它们放在
Vec
中,并在每次插入后排序,这是次优的

type TQIFunc = fn() -> ();

struct TimerQueueItem {
    when: Instant, // when it should run
    name: String,  // for trace only
    what: TQIFunc, // what to run
}

impl Ord for TimerQueueItem {
    fn cmp(&self, other: &TimerQueueItem) -> Ordering {
        other.when.cmp(&self.when)
    }
}

// `PartialOrd` needs to be implemented as well.
impl PartialOrd for TimerQueueItem {
    fn partial_cmp(&self, other: &TimerQueueItem) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl PartialEq for TimerQueueItem {
    fn eq(&self, other: &Self) -> bool {
        self.when == other.when
    }
}

impl Eq for TimerQueueItem {}
类型TQIFunc=fn()->();
结构TimerQueueItem{
when:Instant,//它应该运行的时间
名称:String,//仅用于跟踪
what:TQIFunc,//运行什么
}
TimerQueueItem的impl命令{
fn cmp(&self,其他:&TimerQueueItem)->订购{
其他.when.cmp(&self.when)
}
}
//“PartialOrd”也需要执行。
TimerQueueItem的impl PartialOrd{
fn部分\u cmp(&self,other:&TimerQueueItem)->选项{
一些(self.cmp(其他))
}
}
TimerQueueItem的impl PartialEq{
fn eq(&self,其他:&self)->bool{
self.when==其他.when
}
}
TimerQueueItem{}的impl Eq
TQI1
等于
TQI2
如果它们具有相同的
when
值-实际上我只想按
when
值排序


BinaryHeap
是否会对两个相等的事物做出其他假设,或者只是用于排序?我同意,代码今天所做的并不是一件好事情,不能作为答案的基础;我主要担心的是
binarycheap
并不认为
TQI1
TQI2
的逻辑克隆,因为我断言它们是相等的。

Rust只会对
binarycheap
使用
Ord
特征(而
Ord
特征需要
PartialEq
特征)。你可以在他们筛选堆的地方看到它:

fn筛选(&mut self,start:usize,pos:usize)->usize{
不安全{
//取出'pos'处的值并创建一个孔。
让mut-hole=hole::新建(&mut-self.data,pos);
while hole.pos()>启动{
让父项=(hole.pos()-1)/2;

if hole.element()Rust将只对
二进制堆使用
Ord
特征(而
Ord
特征需要
PartialEq
特征)。您可以在筛选堆的位置看到它:

fn筛选(&mut self,start:usize,pos:usize)->usize{
不安全{
//取出'pos'处的值并创建一个孔。
让mut-hole=hole::新建(&mut-self.data,pos);
while hole.pos()>启动{
让父项=(hole.pos()-1)/2;
if hole.element()的状态为:“使用二进制堆实现的优先级队列”。优先级队列的全部要点是,您可以插入具有相同优先级的不同项目,然后将相同的项目取回。因此,在您的情况下,当
值为
时,您可以有多个具有相同
值的项目,它们仍然是队列中的不同项目。您还可以将完全相同的项目放入队列中两次,您将得到它你放多少回就放多少回

唯一不能保证的是:如果插入几个比较相等的项,则无法保证取回它们的顺序。

状态为:“使用二进制堆实现的优先级队列”。优先级队列的全部要点是,您可以插入具有相同优先级的不同项目,然后将相同的项目取回。因此,在您的情况下,当
值为
时,您可以有多个具有相同
值的项目,它们仍然是队列中的不同项目。您还可以将完全相同的项目放入队列中两次,您将得到它你放多少回就放多少回


你唯一不能保证的是:如果你插入了几个比较相等的项目,那么就不能保证取回它们的顺序。

ty-为什么这个标记不安全-哪个位需要它?这可能是
BinaryHeap
今天实现的方式,但明天可能会有所不同。你应该依赖的唯一保证是r正确的行为是API中记录的行为。@trentcl提出的建议甚至不是一个离谱的建议-Rust的
HashMap
已经被完全重写过一次。@trentcl-BinaryHeap的文档没有说任何关于Eq的内容,只是说我必须实现PartialOrd,这需要Eq。但我同意这一点,只是因为它需要Eq像今天这样工作是没有保证的。但是我打赌有很多代码在二进制堆中存储结构,它们假定Eq并不意味着任何强项-为什么标记为不安全-哪一位需要它?这可能是
BinaryHeap
今天实现的方式,但明天可能会有所不同。唯一的保证是正确行为的依据是API中记录的行为。@trentcl提出的建议甚至都不过分——Rust的
HashMap
已经被完全重写过一次。@trentcl-BinaryHeap的文档没有提到Eq,只是我必须实现PartialOrd,这需要Eq。但我同意但我敢打赌,现在有很多代码将结构存储在二进制堆中,这些代码假定Eq并不意味着什么强项,只需实现一个处理特定用途的包装器,
struct wrapper(MyRealStruct);