我需要一个有序集,所以我使用 BTreeSet。我有一个 Item 结构,其中包含唯一的 id 和可能重复的排名字段。我只希望考虑 id 字段的唯一性并在排名字段上对其进行排序,因此我手动实现了 PartialEq、PartialOrd 和 Ord 来执行此操作,但它没有按我的预期工作
代码如下: Rust 游乐场:https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=89853e19bb56282226711778c63c0605
use std::cmp::Ordering;
use std::collections::BTreeSet;
#[allow(dead_code)]
fn main() {
let mut set = BTreeSet::new();
set.insert(Item {
id: 0,
rank: 0,
});
set.insert(Item {
id: 1,
rank: 1,
});
set.insert(Item {
id: 2,
rank: 1,
});
for item in set.iter() {
println!("{:?}", item);
}
}
#[derive(Debug, Eq)]
struct Item {
id: u32,
rank: u32,
}
impl PartialEq for Item {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl PartialOrd for Item {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Item {
fn cmp(&self, other: &Self) -> Ordering {
self.rank.cmp(&other.rank)
}
}
我得到了输出
Item { id: 0, rank: 0 }
Item { id: 1, rank: 1 }
当我期待的时候
Item { id: 0, rank: 0 }
Item { id: 1, rank: 1 }
Item { id: 2, rank: 1 }
为什么会发生这种情况以及如何解决这个问题?
PartialOrd
的合同之一:
当且仅当a == b
但partial_cmp(a, b) == Some(Equal)
依赖于那些来保持。BTreeSet
您无法使用
BTreeSet
实现您想要的行为,而应该使用自定义容器。