Shape Area Calculator with Trait Objects
This challenge focuses on utilizing trait objects in Rust to create a flexible and extensible system for calculating the area of different shapes. You'll define a Shape trait and then implement it for various concrete shape types (Circle, Rectangle, Triangle). The goal is to store these shapes in a vector of trait objects and calculate the total area of all shapes in the vector.
Problem Description
You are tasked with creating a system that can calculate the total area of a collection of different shapes. To achieve this, you'll define a Shape trait with a single method, area(), which returns the area of the shape as an f64. You will then implement this trait for three concrete shape types: Circle, Rectangle, and Triangle. Each shape type will have its own specific data (radius for Circle, width and height for Rectangle, base and height for Triangle). Finally, you need to create a vector that can hold instances of any of these shape types as trait objects (Vec<Box<dyn Shape>>) and calculate the total area of all shapes stored within the vector.
Key Requirements:
- Define a
Shapetrait with anarea()method that returnsf64. - Implement the
Shapetrait forCircle,Rectangle, andTrianglestructs. Each struct should hold the necessary data for its area calculation. - Create a function
calculate_total_areathat takes aVec<Box<dyn Shape>>as input and returns the total area as anf64. - Demonstrate the usage of the system by creating instances of
Circle,Rectangle, andTriangle, adding them to a vector, and then callingcalculate_total_area.
Expected Behavior:
The calculate_total_area function should iterate through the vector of trait objects, call the area() method on each shape, and sum the results. The returned value should be the total area of all shapes in the vector.
Edge Cases to Consider:
- An empty vector should return 0.0.
- The
area()method should handle potential errors (e.g., negative dimensions) gracefully, although for simplicity, you can assume valid input.
Examples
Example 1:
Input: [Circle { radius: 2.0 }, Rectangle { width: 3.0, height: 4.0 }, Triangle { base: 5.0, height: 6.0 }]
Output: 52.56637061435917
Explanation: Circle area = π * 2^2 ≈ 12.566, Rectangle area = 3 * 4 = 12, Triangle area = 0.5 * 5 * 6 = 15. Total area = 12.566 + 12 + 15 = 39.566 (approximately). Note: The provided output is an approximation due to floating-point calculations.
Example 2:
Input: []
Output: 0.0
Explanation: The vector is empty, so the total area is 0.
Example 3:
Input: [Circle { radius: 1.0 }, Circle { radius: 1.0 }, Circle { radius: 1.0 }]
Output: 9.42477796076938
Explanation: Three circles with radius 1.0. Each circle's area is π * 1^2 ≈ 3.14159. Total area is 3 * 3.14159 ≈ 9.42477.
Constraints
- The
area()method must return anf64. - The vector of shapes can contain a maximum of 100 shapes. (This is for performance considerations, but the code should work correctly with fewer shapes).
- Shape dimensions (radius, width, height, base) will be non-negative.
- The code must compile and run without panics.
Notes
- You'll need to use
Box<dyn Shape>to store trait objects in the vector.dynkeyword is crucial for trait objects. - Consider using
std::f64::consts::PIfor the value of π. - This problem demonstrates polymorphism through trait objects, allowing you to work with different shape types in a uniform way.
- Think about why you need to use
Boxwhen storing trait objects. It's related to the size of the types.