trait Shape {
fn perimeter(&self) -> f32;
fn area(&self) -> f32;
}
struct Rectangle { pub width: f32, pub height: f32 }
struct Triangle { pub side: f32 }
struct Circle { pub radius: f32 }
impl Shape for Rectangle {
fn perimeter(&self) -> f32 {
self.width * 2.0 + self.height * 2.0
}
fn area(&self) -> f32 {
self.width * self.height
}
}
impl Shape for Triangle {
fn perimeter(&self) -> f32 {
self.side * 3.0
}
fn area(&self) -> f32 {
self.side * 0.5 * 3.0_f32.sqrt() / 2.0 * self.side
}
}
impl Shape for Circle {
fn perimeter(&self) -> f32 {
self.radius * 2.0 * std::f32::consts::PI
}
fn area(&self) -> f32 {
self.radius * self.radius * std::f32::consts::PI
}
}
fn print_area(shape: &dyn Shape) {
println!("{}", shape.area());
}
fn print_perimeters(shapes: Vec<&dyn Shape>) {
for shape in shapes.iter() {
println!("{}", shape.perimeter());
}
}
#[test]
pub fn test_dynamic_dispatch() {
let rectangle = Rectangle { width: 1.0, height: 2.0 };
let circle = Circle { radius: 1.0 };
let shapes: Vec<&dyn Shape> = vec![&rectangle, &circle];
for shape in &shapes {
print_area(*shape);
}
print_perimeters(shapes);
print_area(&rectangle);
print_area(&circle);
print_perimeters(vec![ &rectangle, &circle ]);
}