CodexBloom - Programming Q&A Platform

How to implement solution with trait objects and lifetimes when using generic methods in rust

👀 Views: 80 đŸ’Ŧ Answers: 1 📅 Created: 2025-06-08
rust traits lifetimes Rust

I'm relatively new to this, so bear with me. I'm running into a lifetime scenario when trying to use trait objects with a generic method in Rust. Here's my scenario: I have a trait `Shape` with a method `area()`, and I want to create a function that takes a vector of trait objects (`Vec<Box<dyn Shape>>`) and calculates the total area. However, I'm getting a lifetime behavior. Here's the minimal code that reproduces the scenario: ```rust trait Shape { fn area(&self) -> f64; } struct Circle { radius: f64, } impl Shape for Circle { fn area(&self) -> f64 { std::f64::consts::PI * self.radius * self.radius } } fn total_area(shapes: Vec<Box<dyn Shape>>) -> f64 { shapes.iter().map(|s| s.area()).sum() } fn main() { let shapes: Vec<Box<dyn Shape>> = vec![Box::new(Circle { radius: 2.0 })]; let area = total_area(shapes); println!("Total area: {}", area); } ``` When I try to compile this, I get the following behavior: ``` behavior[E0507]: want to move out of `shapes` because it is borrowed --> src/main.rs:8:5 | 8 | shapes.iter().map(|s| s.area()).sum() | ^^^^^^^^^^ move occurs because `shapes` has type `Vec<Box<dyn Shape>>`, which does not implement the `Copy` trait ``` I understand that the `shapes` vector is being borrowed while I'm trying to move values out of it. I attempted to change the function to take a reference to the vector like so: ```rust fn total_area(shapes: &Vec<Box<dyn Shape>>) -> f64 { shapes.iter().map(|s| s.area()).sum() } ``` But that leads to a different behavior. I also tried using `&[Box<dyn Shape>]` instead of `&Vec<Box<dyn Shape>>`, but still face issues. What is the correct way to handle this situation while ensuring I can calculate the total area without running into ownership and borrowing conflicts? Any insights would be greatly appreciated! Is there a better approach?