After reading this answer to "Vector of objects belonging to a trait", it looks like Rust does automatic unboxing. Is this the case?
My code doesn't compile and I don't understand how that answer's code could compile.
What is the correct way to unbox the elements of a polymorphic vector, one containing boxed traits?
I've read Rust by Example and the Box
documentation and I can't see any method that looks like unbox()
.
My code is:
trait HasArea {
fn area(&self) -> f64;
}
struct Circle {
x: f64,
y: f64,
radius: f64,
}
impl HasArea for Circle {
fn area(&self) -> f64 {
std::f64::consts::PI * (self.radius * self.radius)
}
}
struct Square {
x: f64,
y: f64,
side: f64,
}
impl HasArea for Square {
fn area(&self) -> f64 {
self.side * self.side
}
}
fn print_area<T: HasArea>(shape: T) {
println!("This shape has an area of {}", shape.area());
}
fn main() {
let c = Circle {
x: 0.0f64,
y: 0.0f64,
radius: 1.0f64,
};
let s = Square {
x: 0.0f64,
y: 0.0f64,
side: 1.0f64,
};
print_area(c);
print_area(s);
let vec: Vec<Box<HasArea>> = Vec::new();
vec.push(Box::new(c));
vec.push(Box::new(s));
for x in vec {
print_area(x)
}
}
My error is:
Compiling rustgraph v0.1.0 (file:///home/chris/lunch/rustgraph)
error[E0277]: the trait bound `Box<HasArea>: HasArea` is not satisfied
--> src/main.rs:54:9
|
54 | print_area(x)
| ^^^^^^^^^^ the trait `HasArea` is not implemented for `Box<HasArea>`
|
= note: required by `print_area`
You can dereference it like
print_area(*x)
, but it won't work for other reasons: theSized
bound for theprint_area
argument. Your function needs to know the size of its arguments.You have other problems in your code: you are trying to push into an immutable vector and you are trying to box moved values. These were moved after you used it in
print_area()
.My opinion is that it would be easier to make
print_area
a method which takes an immutable reference. This will work as you expected.