Сравнения
Эти трейты поддерживают сравнение значений. Все трейты можно получить через derive для типов, содержащих поля, которые реализуют эти трейты.
PartialEq и Eq
PartialEq — частичное отношение эквивалентности с обязательным методом eq и предоставляемым методом ne. Операторы == и != вызывают эти методы.
// Copyright 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0
struct Key {
id: u32,
metadata: Option<String>,
}
impl PartialEq for Key {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
Eq — полное отношение эквивалентности (рефлексивное, симметричное и транзитивное), и оно подразумевает PartialEq. Функции, которые требуют полной эквивалентности, используют Eq как ограничение трейта.
PartialOrd и Ord
PartialOrd задаёт частичный порядок с методом partial_cmp. Он используется для реализации операторов <, <=, >= и >.
// Copyright 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0
use std::cmp::Ordering;
#[derive(Eq, PartialEq)]
struct Citation {
author: String,
year: u32,
}
impl PartialOrd for Citation {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
match self.author.partial_cmp(&other.author) {
Some(Ordering::Equal) => self.year.partial_cmp(&other.year),
author_ord => author_ord,
}
}
}
Ord — полный порядок, где cmp возвращает Ordering.
-
PartialEqможно реализовать между разными типами, аEqнельзя, потому что он рефлексивен:// Copyright 2023 Google LLC // SPDX-License-Identifier: Apache-2.0 struct Key { id: u32, metadata: Option<String>, } impl PartialEq<u32> for Key { fn eq(&self, other: &u32) -> bool { self.id == *other } } -
На практике эти трейты часто получают через derive, но реализуют их вручную редко.
-
При сравнении ссылок в Rust сравниваются значения того, на что они указывают, а НЕ сами ссылки. Поэтому ссылки на два разных объекта могут сравниваться как равные, если значения, на которые они указывают, одинаковы:
// Copyright 2023 Google LLC // SPDX-License-Identifier: Apache-2.0 fn main() { let a = "Hello"; let b = String::from("Hello"); assert_eq!(a, b); }