Ce face Ord
Ord spune că oricare două valori se pot compara și că rezultatul este mereu clar: mai mic, egal sau mai mare. Metoda cmp returnează direct un Ordering (nu un Option). Îl cer Vec::sort, BTreeMap, BTreeSet, BinaryHeap, Iterator::max și min.
Pentru a-l deriva ai nevoie de toți patru: #[derive(PartialEq, Eq, PartialOrd, Ord)]. Ordinea este cea a câmpurilor, ca la PartialOrd. Când vrei alt criteriu (după notă descrescător, apoi după nume), implementezi manual cmp, iar partial_cmp doar îl apelează: Some(self.cmp(other)). Toate patru trebuie să spună același lucru.
Parametri
| Parametru | Descriere |
|---|---|
cmp(&self, other) |
Singura metodă obligatorie. max, min și clamp vin automat. |
Ce returnează
cmp returnează Ordering: Less, Equal sau Greater.
Exemple
Exemplul 1: cmp pe valori obișnuite
use std::cmp::Ordering;
fn main() {
println!("{:?}", 3.cmp(&7));
println!("{:?}", "Iași".cmp("Cluj"));
println!("{:?}", 'a'.cmp(&'a'));
match 18.cmp(&21) {
Ordering::Less => println!("prea tânăr"),
Ordering::Equal => println!("exact vârsta minimă"),
Ordering::Greater => println!("acces permis"),
}
}
Rezultat
Less
Greater
Equal
prea tânăr
Exemplul 2: Implementare manuală: notă descrescător, apoi nume
use std::cmp::Ordering;
#[derive(PartialEq, Eq)]
struct Elev {
nume: String,
nota: u8,
}
impl Ord for Elev {
fn cmp(&self, other: &Self) -> Ordering {
other.nota.cmp(&self.nota).then_with(|| self.nume.cmp(&other.nume))
}
}
impl PartialOrd for Elev {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
fn main() {
let mut elevi = vec![
Elev { nume: "Radu".into(), nota: 8 },
Elev { nume: "Ioana".into(), nota: 10 },
Elev { nume: "Ana".into(), nota: 10 },
Elev { nume: "Mihai".into(), nota: 9 },
];
elevi.sort();
for (loc, e) in elevi.iter().enumerate() {
println!("{}. {} – {}", loc + 1, e.nume, e.nota);
}
}
Rezultat
1. Ana – 10
2. Ioana – 10
3. Mihai – 9
4. Radu – 8
Exemplul 3: derive(Ord) pe un enum și BTreeSet
use std::collections::BTreeSet;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
enum Prioritate {
Scazuta,
Normala,
Urgenta,
}
fn main() {
let set: BTreeSet<Prioritate> =
[Prioritate::Urgenta, Prioritate::Scazuta, Prioritate::Normala].into_iter().collect();
println!("{set:?}");
println!("cea mai mare: {:?}", set.iter().max());
}
Rezultat
{Scazuta, Normala, Urgenta}
cea mai mare: Some(Urgenta)
Greșeli frecvente
- Implementezi
cmpmanual, dar lași#[derive(PartialOrd)]:<șisortvor folosi criterii diferite. Implementeazăpartial_cmpprinSome(self.cmp(other)). - Scrii
a.cmp(b)în loc dea.cmp(&b):cmpprimește o referință.
Comenzi înrudite
Ordering: Rezultatul unei comparații: Less, Equal sau Greater; are then, then_with și reverse pentru sortări pe mai multe criterii.PartialOrd: Trait-ul din spatele operatorilor <, >, <=, >=; partial_cmp poate returna None (ex. NaN la f64).Ord::max: Returnează cea mai mare (max) sau cea mai mică (min) dintre două valori ale unui tip Ord.Ord::clamp: Limitează o valoare la intervalul [min, max]: sub min devine min, peste max devine max.Eq: Trait marker care promite egalitate completă (a == a mereu); cerut de chei în HashMap/HashSet și de Ord.