Associated Types and Advanced Traits
Generic Traits
A generic trait is a trait parameterized over one or more type parameters (trait Name<T>), allowing a single type to implement the same trait multiple times for different type arguments.
Defining and Implementing a Generic Trait
When a trait has a type parameter T, each impl Trait<ConcreteType> for MyType block is a distinct implementation:
trait ConvertTo<Output> {
fn convert(&self) -> Output;
}
struct TemperatureCelsius(f64);
impl ConvertTo<f64> for TemperatureCelsius {
fn convert(&self) -> f64 {
self.0
}
}
impl ConvertTo<String> for TemperatureCelsius {
fn convert(&self) -> String {
format!("{:.1} °C", self.0)
}
}
fn main() {
let temp = TemperatureCelsius(25.0);
// Type annotations select which implementation of ConvertTo<Output> is called:
let raw: f64 = temp.convert();
let label: String = temp.convert();
println!("raw = {raw}, label = {label}");
}
raw = 25, label = 25.0 °C
Generic Blanket Implementations
A generic trait can also be implemented generically for a family of types by declaring type parameters on the impl<...> header itself:
trait SummarizeFrom<Source> {
fn summarize(src: &Source) -> String;
}
struct Report;
// Implements SummarizeFrom<&[T]> for Report for ANY T that implements Debug:
impl<T: std::fmt::Debug> SummarizeFrom<[T]> for Report {
fn summarize(src: &[T]) -> String {
format!("{} items: {:?}", src.len(), src)
}
}
fn main() {
let numbers = [10, 20, 30];
let words = ["rust", "traits"];
println!("{}", Report::summarize(&numbers[..]));
println!("{}", Report::summarize(&words[..]));
}
3 items: [10, 20, 30]
2 items: ["rust", "traits"]
Standard Library Generic Traits
| Generic Trait | Type Parameter Role | Why It Uses a Generic Parameter |
|---|---|---|
From<T> / Into<T> |
Source or target type T |
One type can convert from/into many different types (String: From<&str>, String: From<char>) |
AsRef<T> / AsMut<T> |
Borrowed view target T |
String can be borrowed as AsRef<str>, AsRef<[u8]>, and AsRef<Path> simultaneously |
PartialEq<Rhs> |
Right-hand operand type | Allows comparing String == &str and String == String |
Index<Idx> |
Index key type Idx |
Vec<T> implements Index<usize>, Index<Range<usize>>, and Index<RangeFull> |