Hone logo
Hone
Problems

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 Shape trait with an area() method that returns f64.
  • Implement the Shape trait for Circle, Rectangle, and Triangle structs. Each struct should hold the necessary data for its area calculation.
  • Create a function calculate_total_area that takes a Vec<Box<dyn Shape>> as input and returns the total area as an f64.
  • Demonstrate the usage of the system by creating instances of Circle, Rectangle, and Triangle, adding them to a vector, and then calling calculate_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 an f64.
  • 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. dyn keyword is crucial for trait objects.
  • Consider using std::f64::consts::PI for 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 Box when storing trait objects. It's related to the size of the types.
Loading editor...
rust