Summary - Trait bounds
- Rust course
- Intermediate
- Lesson 24/115
- 5 min
Combine trait bounds and where to write a generic max function.
Trait bounds summary
A trait bound defines a generic type's behaviour: <T: Display>, several bounds with +, long bounds with where. impl Trait in a parameter is shorthand for a generic; in return position it means a single hidden type. dyn Trait is runtime dispatch; it holds different types in the same collection and is used behind a pointer. The default choice is generics; use dyn when you need a mixed collection or a plugin structure.
Finding the largest area
Iterator methods can be used on trait objects too. Since f64 isn't Ord, the largest is found with fold instead of max:
fn en_buyuk_alan(v: &[Box<dyn Sekil>]) -> f64 {
v.iter().map(|s| s.alan()).fold(0.0, f64::max)
}f64::max, a function taking two arguments, can be passed directly to fold.
Practice Largest area
With the Sekil, Kare and Daire definitions from the previous lesson, write fn en_buyuk_alan(v: &[Box<dyn Sekil>]) -> f64. Print the result with {:.2} for a list containing Kare(2.0), Kare(3.0) and Daire(1.0).
Starter code
trait Sekil {
fn alan(&self) -> f64;
fn ad(&self) -> String;
}
struct Kare(f64);
struct Daire(f64);
impl Sekil for Kare {
fn alan(&self) -> f64 {
self.0 * self.0
}
fn ad(&self) -> String {
String::from("kare")
}
}
impl Sekil for Daire {
fn alan(&self) -> f64 {
std::f64::consts::PI * self.0 * self.0
}
fn ad(&self) -> String {
String::from("daire")
}
}
fn main() {
// buraya yaz
}Sample solution
trait Sekil {
fn alan(&self) -> f64;
fn ad(&self) -> String;
}
struct Kare(f64);
struct Daire(f64);
impl Sekil for Kare {
fn alan(&self) -> f64 {
self.0 * self.0
}
fn ad(&self) -> String {
String::from("kare")
}
}
impl Sekil for Daire {
fn alan(&self) -> f64 {
std::f64::consts::PI * self.0 * self.0
}
fn ad(&self) -> String {
String::from("daire")
}
}
fn en_buyuk_alan(v: &[Box<dyn Sekil>]) -> f64 {
v.iter().map(|s| s.alan()).fold(0.0, f64::max)
}
fn main() {
let v: Vec<Box<dyn Sekil>> = vec![Box::new(Kare(2.0)), Box::new(Kare(3.0)), Box::new(Daire(1.0))];
println!("{:.2}", en_buyuk_alan(&v));
}Expected output
9.00
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 How is a <code>Vec<Box<dyn Sekil>></code> passed to a function taking <code>&[Box<dyn Sekil>]</code>?
- With &v Correct answer
- With v
- v.into()
- It can't be
Explanation: &Vec<T> converts to &[T] automatically (deref coercion).
2 Largest by folding
v.iter().map(|s| s.alan()).____(0.0, f64::max)
v.iter().map(|s| s.alan()).fold(0.0, f64::max)
Explanation: fold combines each element starting from an initial value; with f64::max it finds the largest.
3 Group summary
| Term | Meaning |
|---|---|
<T: A + B> |
Multiple bounds |
where |
Readable bounds |
-> impl Trait |
Single hidden type |
Box<dyn Trait> |
Dynamic dispatch |