capypad
0 day streak
rust / intermediate
Snippet

Generic Functions with Trait Bounds and where Clauses

Generic functions combined with trait bounds create flexible, reusable code. The where clause provides cleaner syntax for complex bounds. Multiple trait bounds (T: Debug + Display) require types to implement all specified traits.

snippet.rs
rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
use std::fmt::{Debug, Display};
 
fn print_debug_and_display<T, U>(t: &T, u: &U)
where
T: Debug + Display,
U: Debug + Clone,
{
println!("t - Debug: {:?}, Display: {}", t, t);
println!("u - Debug: {:?}, Clone: {:?}", u, u.clone());
}
 
fn largest<T: PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list {
if item > largest {
largest = item;
}
}
largest
}
 
#[derive(Debug)]
struct Point<T, U> {
x: T,
y: U,
}
 
impl<T: Debug, U: Debug> Debug for Point<T, U> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Point {{ x: {:?}, y: {:?} }}", self.x, self.y)
}
}
Breakdown
1
where T: Debug + Display
Multiple trait bounds combined, type must implement both
2
fn largest<T: PartialOrd>(list: &[T])
Single trait bound on generic type enables comparison
3
struct Point<T, U>
Generic struct with two type parameters allows flexibility
4
u.clone()
Clone bound enables duplication of values when needed