我有一个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
的文档说:
PartialEq
、PartialOrd
和Ord
的实现必须符合彼此通过推导一些并手动实现其他特性。
换句话说,您需要确保(a == b) == (a.cmp(b) == Ordering::Equal)
,因为允许其他代码(例如BTreeSet
(假设此属性成立;否则,你可能会有不正确(但并非不安全(的行为。
这个想法是
BTreeSet
中的结构应该按thing_to_compare
排序
排序是btree的内部组织方式,就像HashSets的Hash/Eq一样。这意味着CCD_ 24是BTreeSet的";身份;信息,它不仅仅是表面级别的显示或迭代顺序。
我感到困惑的是,为什么BTreeSet不使用自动生成的Eq特征或PartialEq特征来检查值是否存在于其内部。
因为为什么会这样?Ord
是它所需要的,也是它用来内部探测自身的。如果Ord
被破坏,那么忘记相等,整个集合将在内部不一致。