Multiple traits
- Rust course
- Intermediate
- Lesson 5/115
- 4 min
Implement multiple traits for one type.
Multiple traits
A type can implement as many traits as it wants. If a parameter needs several behaviours, the traits are combined with +:
use std::fmt::Display;
fn rapor(x: &(impl Display + Ozet)) -> String {
format!("{x} ({})", x.ozet())
}Here x must both be printable with {} (Display) and have the ozet() method. The parentheses are needed so that & applies to both traits together.
Display and a custom trait together
A score type can be both printable and able to summarize itself:
struct Puan(u32);
impl Display for Puan {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{} puan", self.0)
}
}
impl Ozet for Puan {
fn ozet(&self) -> String {
if self.0 > 50 { "yüksek".into() } else { "düşük".into() }
}
}Practice Score report
Write the Ozet trait and the type struct Puan(u32);; implement Display ("N puan") and Ozet ("yüksek" above 50, otherwise "düşük") for Puan. With fn rapor(x: &(impl Display + Ozet)) -> String, print the reports for Puan(80) and Puan(20) on separate lines.
Starter code
use std::fmt::Display;
fn main() {
// buraya yaz
}Sample solution
use std::fmt::Display;
trait Ozet {
fn ozet(&self) -> String;
}
struct Puan(u32);
impl Display for Puan {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{} puan", self.0)
}
}
impl Ozet for Puan {
fn ozet(&self) -> String {
if self.0 > 50 {
"yüksek".into()
} else {
"düşük".into()
}
}
}
fn rapor(x: &(impl Display + Ozet)) -> String {
format!("{x} ({})", x.ozet())
}
fn main() {
println!("{}", rapor(&Puan(80)));
println!("{}", rapor(&Puan(20)));
}Expected output
80 puan (yüksek) 20 puan (düşük)
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 If two traits have a method with the same name <code>ad()</code> and a type implements both, how do you call a specific one?
- x.ad() always picks the first
- It isn't possible
- x.ad::<Trait>()
- With the full path TraitName::ad(&x) Correct answer
Explanation: On ambiguity the compiler errors (E0034); TraitName::method(&x) or <T as Trait>::method(&x) says which one is meant.
2 Ask for two behaviours
fn rapor(x: &(impl Display ____ Ozet)) -> String {
format!("{x} ({})", x.ozet())
}
fn rapor(x: &(impl Display + Ozet)) -> String {
format!("{x} ({})", x.ozet())
}
Explanation: Trait bounds are combined with +.
3 Score and rapor result
| Term | Meaning |
|---|---|
Puan(80) |
80 puan (yüksek) |
Puan(20) |
20 puan (düşük) |
Puan(51) |
51 puan (yüksek) |
Puan(50) |
50 puan (düşük) |