Rust
Beginner
1 min read
Trait Bounds and Static Dispatch
Example
use std::fmt::{Debug, Display};
// Trait bounds with + syntax
fn print_both<T: Debug + Display>(value: T) {
println!("Display: {value}");
println!("Debug: {value:?}");
}
// where clause — cleaner for multiple generics
fn compare_and_print<T, U>(a: T, b: U)
where
T: Display + PartialOrd,
U: Debug,
{
println!("a={a} b={b:?}");
}
// impl Trait in parameter position — anonymous generic
fn summarise(item: impl Display) -> String {
format!("[{}]", item)
}
// impl Trait in return position — hides the concrete type
fn make_adder(x: i32) -> impl Fn(i32) -> i32 {
move |y| x + y
}
// A generic struct with a trait bound
#[derive(Debug)]
struct Wrapper<T: Display> {
value: T,
}
impl<T: Display> Wrapper<T> {
fn show(&self) {
println!("wrapped: {}", self.value);
}
}
fn main() {
print_both(42);
print_both("hello");
compare_and_print(3.14f64, vec![1, 2, 3]);
println!("{}", summarise(100));
println!("{}", summarise("world"));
let add5 = make_adder(5);
println!("5 + 10 = {}", add5(10));
let w = Wrapper { value: "rust" };
w.show();
}