Hone logo
Hone
Problems

Dynamic Behavior with Trait Objects in Rust

This challenge focuses on leveraging Rust's trait objects to achieve dynamic dispatch. You'll create a system where different types can be treated uniformly through a shared interface, enabling flexible and extensible code. This is a fundamental concept for building polymorphic behavior in Rust when static dispatch isn't sufficient.

Problem Description

Your task is to implement a system that can process a collection of diverse shapes. Each shape will have a method to calculate its area. You need to be able to store these different shapes in a single collection and call their area method polymorphically.

Requirements:

  1. Define a trait named Shape with a single method: area(&self) -> f64.
  2. Implement this Shape trait for at least two different concrete types, for example, Circle and Rectangle.
  3. Create a function that accepts a collection of Shape trait objects (e.g., Vec<Box<dyn Shape>>) and calculates the total area of all shapes in the collection by iterating through them and calling their respective area methods.
  4. The Circle and Rectangle structs should store relevant data to calculate their areas (e.g., radius for Circle, width and height for Rectangle).

Expected Behavior:

When the function processes a collection of Circle and Rectangle objects, it should correctly calculate and return the sum of their individual areas. The area method should be invoked on each object based on its underlying concrete type, demonstrating dynamic dispatch.

Edge Cases:

  • Consider how to handle an empty collection of shapes.

Examples

Example 1:

Input:
Shapes: [Circle { radius: 5.0 }, Rectangle { width: 4.0, height: 6.0 }]

Output:
Total Area: 101.53981633974483

Explanation: The area of the Circle with radius 5.0 is π * 5.0^2 ≈ 78.5398. The area of the Rectangle with width 4.0 and height 6.0 is 4.0 * 6.0 = 24.0. The total area is approximately 78.5398 + 24.0 = 102.5398. (Note: The exact output will depend on the precision of f64 and PI used.)

Example 2:

Input:
Shapes: [Rectangle { width: 2.0, height: 3.0 }, Circle { radius: 2.0 }]

Output:
Total Area: 18.84955592153876

Explanation: The area of the Rectangle with width 2.0 and height 3.0 is 2.0 * 3.0 = 6.0. The area of the Circle with radius 2.0 is π * 2.0^2 ≈ 12.56637. The total area is approximately 6.0 + 12.56637 = 18.56637.

Example 3:

Input:
Shapes: []

Output:
Total Area: 0.0

Explanation: An empty collection of shapes should result in a total area of 0.0.

Constraints

  • The area method should return a f64.
  • Use Box<dyn Shape> to store the trait objects in the collection.
  • The implementation should be reasonably efficient for typical collections, but extreme performance optimization is not the primary focus.

Notes

  • You will need to import the PI constant from the std::f64::consts module.
  • Consider how to create instances of your concrete shape types and then wrap them in Box<dyn Shape>.
  • This challenge tests your understanding of dyn Trait syntax and the concept of dynamic dispatch.
Loading editor...
rust