Rust Fundamentals · 15 XP Pro

Trait bounds

A generic function can accept any type, but then it can do almost nothing with it. A trait bound says what the type must be able to do:

fn loudest<T: Volume>(items: &[T]) -> Option<&T> {
    items.iter().max_by_key(|i| i.volume())
}

T: Volume means "any T that implements Volume", so calling .volume() is allowed. When you only need the bound once, impl Trait in argument position is a shorter spelling of the same idea:

fn shout(item: &impl Volume) -> String {
    format!("volume {}", item.volume())
}

Your task

The starter defines the trait Score and two types that implement it. Everything must stay pub, because the tests use your crate as lesson. Write:

  1. pub fn best<T: Score>(items: &[T]) -> Option<&T> returning the item with the highest score(), or None for an empty slice (tests never use ties).
  2. pub fn describe(item: &impl Score) -> String returning format!("score: {}", item.score()).

Next lesson →

Sign in to run your code. It's free.