我已经为我的结构实现了PartialEqand PartialOrd,所以我可以BTreeSet使用一些自定义逻辑创建这些结构的 s:如果结构中的名称字段等于另一个结构的名称字段,则结构相等。当我查找一个结构体是否在这个集合中时,它只在整个结构体在集合中而不仅仅是名称字段时才返回 true。我该如何解决这个问题,以便两个断言都返回 true?
use std::cmp::Ordering;
use std::collections::BTreeSet;
#[derive(Debug, Eq, Hash, Ord)]
struct Obj {
name: String,
count: i64,
}
impl PartialEq for Obj {
fn eq(&self, other: &Self) -> bool {
self.name == other.name
}
}
impl PartialOrd for Obj {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.name.cmp(&other.name))
}
}
fn vec_to_set(v: &[&str]) -> BTreeSet<Obj> {
let hs: BTreeSet<Obj> = v
.iter()
.map(|d| {
let mut count = 1;
if d.to_string() == "C".to_string() {
count = 2;
};
Obj {
name: d.to_string(),
count,
}
})
.collect();
hs
}
fn main() {
let v = vec!["A", "B", "C", "A"];
let hs = vec_to_set(&v);
let t1 = Obj {
name: "A".to_string(),
count: 1,
};
let t2 = Obj {
name: "A".to_string(),
count: 10,
};
assert!(hs.contains(&t1)); // true
assert!(hs.contains(&t2)); // false
}
Run Code Online (Sandbox Code Playgroud)
您不能手动实现PartialOrd或PartialEq和派生Ord。不同的实现必须相互一致,默认生成的Ord实现与您手动实现的不同。
如果你替换#[derive(Ord)]为
impl Ord for Obj {
fn cmp(&self, other: &Self) -> Ordering {
self.name.cmp(&other.name)
}
}
Run Code Online (Sandbox Code Playgroud)
您的程序按预期工作。
然而,您可以在派生Eq时派生PartialEq,因为Eq它只是一个标记特征,所以它的派生实现不能与您的实现相矛盾。
的派生实现Hash 也与 的手动实现不一致PartialEq。BTreeSet不使用Hash, butHashMap和HashSetdo ,并且他们也会对派生的Hashimpl行为不端。
| 归档时间: |
|
| 查看次数: |
135 次 |
| 最近记录: |