fad*_*bee 3 boxing vector rust
在阅读了"属于特征的对象的向量"的答案之后,看起来Rust会自动取消装箱.是这样的吗?
我的代码没有编译,我不明白该答案的代码如何编译.
解包多态向量元素的正确方法是什么,包含盒装特征?
我读过通过实例锈和的Box
文档,我不能看到像这样的任何方法unbox()
.
我的代码是:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
我的错误是:
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`
Run Code Online (Sandbox Code Playgroud)
您可以取消引用它print_area(*x)
,但由于其他原因它不起作用:参数的Sized
界限print_area
.您的函数需要知道其参数的大小.
您的代码中还有其他问题:您正在尝试推入不可变向量,并且您尝试将移动的值设置为空.这些都是在您使用它之后移动的print_area()
.
我的观点是,制作print_area
一个采用不可变引用的方法会更容易.这将按预期工作.
trait HasArea {
fn area(&self) -> f64;
fn print_area(&self) {
println!("This shape has area of {}", self.area());
}
}
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,
};
c.print_area();
s.print_area();
let mut vec: Vec<Box<HasArea>> = Vec::new();
vec.push(Box::new(c));
vec.push(Box::new(s));
for x in vec {
x.print_area();
}
}
Run Code Online (Sandbox Code Playgroud)
要回答您的直接问题:
如何拆箱包含在多态向量中的元素?
你不能。一旦某些东西被装箱并擦除了具体类型,就是这样。ABox<SomeTrait>
不能变回 a SomeConcreteType
,因为没有人知道具体类型是什么。
解决代码中的问题...再次查看错误信息:
特征界限
Box<HasArea>: HasArea
不满足
那是因为对特征(或特征框)的引用没有实现该特征!
为了让你的程序像你最初编写的那样编译和运行,你只需要为 box 实现 trait,我们也可以做引用:
impl<T: ?Sized> HasArea for Box<T>
where T: HasArea
{
fn area(&self) -> f64 { (**self).area() }
}
impl<'a, T: ?Sized> HasArea for &'a T
where T: HasArea
{
fn area(&self) -> f64 { (**self).area() }
}
Run Code Online (Sandbox Code Playgroud)
这允许您的固定主程序运行:
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![Box::new(c), Box::new(s)];
for x in vec {
print_area(x)
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,我们传递的参考c
,并s
到print_area
,为了避免过户。我们还使用vec!
宏以更少的仪式来构造向量。