BTreeSet包含值(使用自定义Ord实现),并错误地为"contains"返回true



我有一个BTreeSet,它存储类型为的值

#[derive(Debug, Eq)]
pub struct Foo {
pub a: usize,
pub thing_to_compare: usize,
}
impl Ord for PriorityEntry {
fn cmp(&self, other: &Self) -> Ordering {
// Sort in reverse order
other.thing_to_compare.cmp(&self.thing_to_compare)
}
}
impl PartialOrd for PriorityEntry {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl PartialEq for PriorityEntry {
fn eq(&self, other: &Self) -> bool {
self.a == other.a && self.thing_to_compare == other.thing_to_compare
}
}

其思想是BTreeSet中的结构应按thing_to_compare排序,而a字段只是附加信息。

我注意到,如果我有一个带的BTreeSet

{ a: 0, thing_to_compare: 0 }

则CCD_ 6将返回用于的CCD_

{ a: 1, thing_to_compare: 0 }

我猜它返回true是因为cmp将为这两个值返回Ordering::Equal,因为它们具有相同的thing_to_compare。我感到困惑的是,为什么BTreeSet不使用自动生成的Eq特征或PartialEq特征来检查该值是否存在于其内部。

毕竟,我认为Ord特征应该只与排序相关,而与两个值是否相同无关。

Ord的文档说:

PartialEqPartialOrdOrd的实现必须符合彼此通过推导一些并手动实现其他特性。

换句话说,您需要确保(a == b) == (a.cmp(b) == Ordering::Equal),因为允许其他代码(例如BTreeSet(假设此属性成立;否则,你可能会有不正确(但并非不安全(的行为。

这个想法是BTreeSet中的结构应该按thing_to_compare排序

排序是btree的内部组织方式,就像HashSets的Hash/Eq一样。这意味着CCD_ 24是BTreeSet的";身份;信息,它不仅仅是表面级别的显示或迭代顺序。

我感到困惑的是,为什么BTreeSet不使用自动生成的Eq特征或PartialEq特征来检查值是否存在于其内部。

因为为什么会这样?Ord是它所需要的,也是它用来内部探测自身的。如果Ord被破坏,那么忘记相等,整个集合将在内部不一致。

相关内容

最新更新