Rust Tutorial · Traits and Generics · Lesson 21 of 29
Rust Generics and Trait Bounds
Write functions and types that work with many types, constrained by trait bounds and where clauses.
Generic functions
fn largest<T: PartialOrd>(items: &[T]) -> &T works for any T that can be compared. The bound says what
T must support; the compiler generates specialised code for each type used (zero runtime cost).
use std::fmt::Display;
fn largest<T: PartialOrd>(items: &[T]) -> &T {
let mut best = &items[0];
for item in items {
if item > best { best = item; }
}
best
}
struct Pair<T> { a: T, b: T }
impl<T> Pair<T>
where
T: PartialOrd + Display,
{
fn show_bigger(&self) -> String {
if self.a >= self.b { format!("{}", self.a) } else { format!("{}", self.b) }
}
}
fn evens(limit: u32) -> impl Iterator<Item = u32> {
(0..limit).filter(|n| n % 2 == 0)
}
fn main() {
println!("{}", largest(&[3, 9, 4]));
println!("{}", largest(&["pear", "apple", "zucchini"]));
println!("{}", Pair { a: 2.5, b: 1.0 }.show_bigger());
println!("{:?}", evens(10).collect::<Vec<_>>());
}
Output
9 zucchini 2.5 [0, 2, 4, 6, 8]
Run this on your computer — see “Get Started” for setup.
impl Trait
fn print_all(items: impl IntoIterator<Item = impl Display>) is shorthand for a generic parameter, and
-> impl Iterator<Item = u32> returns some type implementing a trait without naming it.
Test yourself
What does the bound T: PartialOrd mean?
T must be a numberT must support comparison with < and >T is optionalT is a reference
Show answer
Answer: T must support comparison with < and >