CodeBlanks Logo Icon CodeBlanks

Multiple traits

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

main.rs
use std::fmt::Display;

fn main() {
    // buraya yaz
}

Sample solution

main.rs
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

Question
fn rapor(x: &(impl Display ____ Ozet)) -> String {
    format!("{x} ({})", x.ozet())
}
Answer
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)

All lessons in Intermediate