A trait defines behavior that different Rust types can share without sharing a state layout or an inheritance hierarchy. The trait names the behavior; each type’s implementation supplies it. Use traits when code needs a capability rather than a particular concrete type. section 2.2 section 2.2.1
A definition can be as small as `trait MinimalTrait {}`. More commonly, it declares methods that implementations must supply; methods may also have defaults. An `impl Trait for Type` attaches the behavior to a type. Traits can specify generic placeholders or require other traits through bounds. section 2.2.2
Listing 2.4 Implementing the Rectangular trait
pub trait Rectangular { #1
fn get_width(&self) -> i32;
fn get_height(&self) -> i32;
fn get_area(&self) -> i32;
}
impl Rectangular for Rectangle { #2
fn get_width(&self) -> i32 {
self.width
}
fn get_height(&self) -> i32 {
self.height
}
fn get_area(&self) -> i32 {
self.width * self.height
}
}
impl Rectangular for Square { #3
fn get_width(&self) -> i32 {
self.length
}
fn get_height(&self) -> i32 {
self.length
}
fn get_area(&self) -> i32 {
self.length * self.length
}
}
Compare the `Rectangular` implementations for `Rectangle` and `Square`: both expose width, height, and area while storing dimensions differently. The repeated implementations separate shared behavior from each type’s state. section 2.2.3
Require a capability in generic code
A generic function cannot call `t.describe()` merely because its parameter is named `T`. Define `SelfDescribing` with `fn describe(&self) -> String`, implement it for each accepted type, and constrain the function with `T: SelfDescribing`. The bound can appear inline or in a `where` clause. Without it, the compiler reports that the method is unavailable; without an implementation for a caller’s type, it reports an unsatisfied bound. If description needs no instance, the method can omit `&self` and be called as `T::describe()`. section 2.2.4
error[E0599]: no method named `describe` found for reference `&T` in
the current scope
--> src/main.rs:6:7
|
6 | t.describe()
| ^^^^^^^^ method not found in `&T`
|
= help: items from traits can only be used if the type parameter is
bounded by the trait
help: the following trait defines an item `describe`, perhaps you need to
restrict type parameter `T` with it:
|
5 | fn describe_type<T: SelfDescribing>(t: &T) -> String {
| ~~~~~~~~~~~~~~~~~
For more information about this error, try `rustc --explain E0599`.
The compiler error pinpoints the missing bound on `T` and suggests `T: SelfDescribing`. It is a useful check when a method call works on a concrete type but not in a generic function. section 2.2.4
For common traits, `#[derive(Clone, Debug, Default)]` can generate implementations instead of handwritten boilerplate. Write an implementation when its behavior must differ: a manual `Default` can supply chosen field values rather than the derived defaults. section 2.2.5
Traits are not a substitute for argument overloading. Two traits can give one type identically named methods, but an unqualified call may be ambiguous even when the signatures differ; bounds or explicit trait qualification clarify which method is meant. Use the flexibility deliberately: excessive traits can create pollution or duplication, and implementations involving external types face restrictions intended to prevent conflicts. section 5.2.4 section 7.2



