请将此视为原始答案的附录,适合您的具体情况。该答案涉及您问题的第二部分。
考虑这个结构:
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因为有些类型的值不能始终进行比较,例如浮点数。NaNs 不是可表示的数字;诸如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)
}
}