Generics and trait bounds
Generics and trait bounds
A helper can compare marks of several numeric types without duplicating the same logic. A generic parameter names a type supplied at use sites. A trait bound states the operations that type must support, allowing the compiler to check the helper independently of a particular call.
What you’ll learn
- State the operations a generic helper requires.
- Recognize that partial comparison is not full numeric validation.
Generics and trait bounds in action
Integer call: 70 versus 80
The integer call uses a suitable integer type and returns 80.
Integer call: 70 versus 80Float call: 77.5 versus 80
The floating-point call returns 80.0, displayed as 80 by default formatting.
Float call: 77.5 versus 80Bounded helper selects a value
The same source logic is checked against the operations promised by the bounds.
Bounded helper selects a value
Generics and trait bounds explained
T: PartialOrd + Copy requires comparison and copyable values. PartialOrd describes types for which comparisons may be partial rather than a complete order. This example returns an owned copy; a different API could borrow the selected input instead. A where clause can make longer bounds easier to read.
Work through the Rust program
Save the complete source as main.rs in the Rust environment. No standard input is needed.
Rust 2024 · complete program
fn higher<T: PartialOrd + Copy>(a: T, b: T) -> T {
if a >= b { a } else { b }
}
fn main() {
println!("{}", higher(70, 80));
println!("{}", higher(77.5, 80.0));
}Expected output
80
80Follow the execution
The integer call uses a suitable integer type and returns 80. The floating-point call returns 80.0, displayed as 80 by default formatting. The same source logic is checked against the operations promised by the bounds.
Try the complete program in the Rust compiler. For tests, Cargo commands and local files, use the specified local environment.
Try a small variation
Your task: Can you pass arbitrary structs that have no comparison implementation?
Rust 2024 · complete program
fn higher<T: PartialOrd + Copy>(a: T, b: T) -> T {
if a >= b { a } else { b }
}
fn main() {
println!("{}", higher(70, 80));
println!("{}", higher(77.5, 80.0));
}Worked answer
No. The function requires PartialOrd. Implement an appropriate comparison or redesign the helper to accept a comparison operation.
Mistakes and limits to recognize
Floating-point NaN does not behave like an ordinary totally ordered value, so this simple helper is not a complete numeric validation policy. Generics can lead to specialized compiled code; they are not dynamic typing.
Check your understanding
Take the idea into your next program
No. The function requires PartialOrd. Implement an appropriate comparison or redesign the helper to accept a comparison operation. Floating-point NaN does not behave like an ordinary totally ordered value, so this simple helper is not a complete numeric validation policy.
Further reading: the official Rust Book on generics and trait bounds.
Reaching the recap and completing the quizzes are separate milestones.