Rust Comparing Values
PartialEq and Ord are traits that compare values in Rust. Ordering is the three-way answer type a comparison returns.
Equality with == and !=
== and != come from the PartialEq trait, which numbers, chars, text, and most standard types provide.
let a = 7;
let b = 12;
println!("equal: {}", a == b);
println!("different: {}", a != b);cmp gives the whole answer at once
cmp returns one of three answers: Ordering::Less, Ordering::Equal, or Ordering::Greater.
println!("{:?}", 7.cmp(&12));
println!("{:?}", 12.cmp(&7));
println!("{:?}", 3.cmp(&3));min and max pick one
Ask two values which is larger, or which is smaller:
println!("bigger = {}", 7.max(12));
println!("smaller = {}", 7.min(12));Floats: the comparison can fail
A float can be NaN — the not-a-number value — which cannot be ordered against anything. So partial_cmp answers with an Option.
println!("{:?}", 1.5.partial_cmp(&2.5));
println!("{:?}", f64::NAN.partial_cmp(&1.0));Sort floats with partial_cmp
sort_by compares each pair with partial_cmp. The unwrap is safe once you know the list holds no NaN.
let mut temps = vec![21.5, 18.0, 25.25];
temps.sort_by(|a, b| a.partial_cmp(b).unwrap());
println!("{:?}", temps);Example
use std::cmp::Ordering;
fn main() {
let a = 7;
let b = 12;
println!("cmp = {:?}", a.cmp(&b));
println!("bigger = {}", a.max(b));
println!("smaller = {}", a.min(b));
let mut temps = vec![21.5, 18.0, 25.25, 19.75];
temps.sort_by(|x, y| x.partial_cmp(y).unwrap());
println!("sorted = {:?}", temps);
let odd = f64::NAN;
println!("nan cmp = {:?}", odd.partial_cmp(&1.0));
match 3.cmp(&3) {
Ordering::Equal => println!("they match"),
_ => println!("different"),
}
}Key points
- cmp needs the Ord trait.
- The trait is a promise.
- Every pair of values has one definite order.
- Integers, chars and text all keep it
- Floats keep only part of the promise.
- f64 has PartialOrd but not Ord.
- NaN is the not-a-number value.
- It cannot be ordered against anything
- If sort() refuses your list, the item type is probably a float — that refusal is the partial_cmp warning sign.
- Comparison traits let values be checked for equality and order.
In this example, a is 7 and b is 12. a.cmp(&b) gives the three-way answer Less. max and min pick 12 and 7. The temps list holds floats, so it cannot use sort(). Instead, sort_by compares pairs with partial_cmp. It unwraps each answer. The list comes out in order: 18.0, 19.75, 21.5, 25.25. The odd value is NaN, and its partial_cmp against 1.0 returns None: no order exists. The last match compares 3 with 3 and takes the Equal arm, printing they match.
Note
sort() works directly on integers and text because they are Ord.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Rust Playground
Exercise
Why does 1.5.partial_cmp(&2.5) return an Option, when 5.cmp(&9) returns Ordering directly?