请将此视为原始答案的附录,适合您的具体情况。该答案涉及您问题的第二部分。
考虑这个结构:
struct Person {
id: u32,
name: String,
height: u32,
}
平等:PartialEq
和Eq
特征
PartialEq Trait,来自文档
Trait for equality comparisons which are partial equivalence
relations. This trait allows for partial equality, for types that do not
have a full equivalence relation. For example, in floating point numbers
NaN != NaN, so floating point types implement PartialEq but not Eq.
Formally, the equality must be (for all a, b and c):
symmetric: a == b implies b == a; and
transitive: a == b and b == c implies a == c.
所以如果你想表达你的类型的值相等意味着什么,你必须实现这个PartialEq
特征。实现它允许我们为我们的类型编写x == y
和x != y
。
impl PartialEq for Person {
fn eq(&self, other: &Person) -> bool {
self.height == other.height
}
}
请注意,我们Person
只是根据高度来决定 struct 的相等性。eq
如果您想比较每个结构字段,您也可以实现此方法:
fn eq(&self, other: &Person) -> bool {
self.id == other.id && self.name == other.name && self.height == other.height
}
但是,#[derive(PartialEq)]
如果这是您想要的行为,那么简单地添加会更容易。
Eq Trait , 来自文档
Trait for equality comparisons which are equivalence relations.
This means, that in addition to a == b and a != b being strict inverses,
the equality must be (for all a, b and c):
reflexive: a == a;
symmetric: a == b implies b == a; and
transitive: a == b and b == c implies a == c.
This property cannot be checked by the compiler, and therefore Eq implies
PartialEq, and has no extra methods.
Derivable
This trait can be used with #[derive]. When derived, because Eq has no extra methods,
it is only informing the compiler that this is an equivalence relation rather than a
partial equivalence relation. Note that the derive strategy requires all
fields are Eq, which isn't always desired.
PartialEq 适用于不一定是自反的关系(即可以有这样的 x 使得 x != x)并且 Eq 是一个标记特征,它表示关系也是自反的(现在它是一个适当的等价关系)。
您还可以Eq
使用空的 impl 块手动实现特征
impl Eq for Person {}
Eq
但是,同样,添加到您的#[derive(Eq)]
列表更容易。
排序:PartialOrd
和Ord
特征
<
使用运算符、<=
和计算值>=
的相对顺序>
。要为您自己的类型实现这些,您必须实现PartialOrd
特征。
在你可以实施之前PartialOrd
,你必须实施PartialEq
。
impl PartialOrd for Person {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
Ordering
是具有这些值的枚举:
pub enum Ordering {
Less,
Equal,
Greater,
}
partial_cmp
返回 anOption
而不是 an,Ordering
因为有些类型的值不能始终进行比较,例如浮点数。NaN
s 不是可表示的数字;诸如3.0 < NaN
没有任何意义的表达。在这些情况下,partial_cmp
返回None
. 浮点值是标准库中唯一发生这种情况的情况。更多可以在这里找到。
partial_cmp
返回 an的事实Option<Ordering>
有一个结果:可能无法将两个值 x 和 y 置于明确的顺序中。实际上,这意味着实施PartialOrd
不足以使您的值可排序。您还需要实现该Ord
特征。
在你可以实施之前Ord
,你必须先实施PartialOrd
,Eq
并且PartialEq
。
对于我们的Person
结构,我们可以再次委托给我们的成员变量之一:
impl Ord for Person {
fn cmp(&self, other: &Person) -> Ordering {
self.height.cmp(&other.height)
}
}