Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vector 如何取消包含在多态向量中的元素的装箱?_Vector_Rust_Boxing - Fatal编程技术网

Vector 如何取消包含在多态向量中的元素的装箱?

Vector 如何取消包含在多态向量中的元素的装箱?,vector,rust,boxing,Vector,Rust,Boxing,阅读后,它看起来像生锈自动拆箱。是这样吗 我的代码没有编译,我不明白答案的代码是如何编译的 对于包含装箱特征的多态性载体,取消装箱的正确方法是什么 我已经读过并且没有看到任何类似于unbox()的方法 我的代码是: trait HasArea { fn area(&self) -> f64; } struct Circle { x: f64, y: f64, radius: f64, } impl HasArea for Circle {

阅读后,它看起来像生锈自动拆箱。是这样吗

我的代码没有编译,我不明白答案的代码是如何编译的

对于包含装箱特征的多态性载体,取消装箱的正确方法是什么

我已经读过并且没有看到任何类似于
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)
    }
}
trait区域{
fn区域(自身)->f64;
}
结构圆{
x:f64,
y:f64,
半径:f64,
}
圆的面积{
fn区域(自身)->f64{
std::f64::consts::PI*(self.radius*self.radius)
}
}
结构广场{
x:f64,
y:f64,
侧面:f64,
}
广场面积{
fn区域(自身)->f64{
自我侧,自我侧
}
}
fn打印区域(形状:T){
println!(“此形状的面积为{}”,shape.area());
}
fn main(){
设c=圆{
x:0.0f64,
y:0.0f64,
半径:1.0f64,
};
让s=平方{
x:0.0f64,
y:0.0f64,
侧面:1.0f64,
};
打印区(c);
打印区;
让vec:vec=vec::new();
向量推送(Box::new(c));
矢量推送(框:新);
对于向量中的x{
打印区域(x)
}
}
我的错误是:

编译rustgraph v0.1.0(file:///home/chris/lunch/rustgraph)
错误[E0277]:未满足特征绑定'Box:HasArea'
-->src/main.rs:54:9
|
54 |打印面积(x)
|^^^^^^^^^^^^未为` Box'实现特性'HasArea'`
|
=注:“打印”区域需要`

您可以像
print\u area(*x)
那样取消对它的引用,但由于其他原因,它将不起作用:为
print\u area
参数绑定的
大小。函数需要知道其参数的大小

您的代码中还有其他问题:您试图推入一个不可变的向量,并且试图将移动的值装箱。在
print\u area()
中使用后,这些已被移动

我的意见是,将
print\u 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();
    }
}
trait区域{
fn区域(自身)->f64;
fn打印区域(自身(&S){
println!(“此形状的面积为{}”,self.area());
}
}
结构圆{
x:f64,
y:f64,
半径:f64,
}
圆的面积{
fn区域(自身)->f64{
std::f64::consts::PI*(self.radius*self.radius)
}
}
结构广场{
x:f64,
y:f64,
侧面:f64,
}
广场面积{
fn区域(自身)->f64{
自我侧,自我侧
}
}
fn打印区域(形状:&T){
println!(“此形状的面积为{}”,shape.area());
}
fn main(){
设c=圆{
x:0.0f64,
y:0.0f64,
半径:1.0f64,
};
让s=平方{
x:0.0f64,
y:0.0f64,
侧面:1.0f64,
};
c、 打印区域();
s、 打印区域();
让mut-vec:vec=vec::new();
向量推送(Box::new(c));
矢量推送(框:新);
对于向量中的x{
x、 打印区域();
}
}
阅读后,看起来锈会自动拆箱。是这样吗

不像你想象的那么自动。实际上,您正在寻找
unbox
方法,而
Box
为目标
T
实现
Deref
。这意味着您应该将
调用为_ref()
或依赖
Deref
强制。请注意,
T
对于未分级的类型是不可能的,因为您依赖多态类型,所以使用者函数必须接受引用

我擅自修复了
main
print\u区域
,使其正常工作。该向量也被不正确地声明为不可变

fn print_area<T: HasArea + ?Sized>(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 mut vec: Vec<Box<HasArea>> = Vec::new();
    vec.push(Box::new(c));
    vec.push(Box::new(s));

    for x in vec {
        print_area(&*x)
    }
}
fn打印区域(形状:&T){
println!(“此形状的面积为{}”,shape.area());
}
fn main(){
设c=圆{
x:0.0f64,
y:0.0f64,
半径:1.0f64,
};
让s=平方{
x:0.0f64,
y:0.0f64,
侧面:1.0f64,
};
打印区域(&c);
打印区域(&s);
让mut-vec:vec=vec::new();
向量推送(Box::new(c));
矢量推送(框:新);
对于向量中的x{
打印区域(&*x)
}
}

作为E_net4建议的替代方案,您可以使用带有参考的
Vec
,而不是将您的特征装箱:

fn print_area<T: HasArea+?Sized>(shape: &T) {
    println!("This shape has an area of {}", shape.area());
}

let mut vec: Vec<&HasArea> = Vec::new();
vec.push(&c);
vec.push(&s);

for x in vec {
    print_area(x)
}
fn打印区域(形状:&T){
println!(“此形状的面积为{}”,shape.area());
}
让mut-vec:vec=vec::new();
向量推送(&c);
向量推送(&s);
对于向量中的x{
打印区域(x)
}
要回答您的直接问题:

如何取消包含在多态向量中的元素的装箱

不能。一旦某个东西被装箱并删除了混凝土类型,就这样了。无法将
制作回
SomeConcreteType
,因为没有人知道该具体类型是什么


要解决代码中的问题。。。再次检查错误消息:

特征绑定
框:HasArea
不满足

那是因为引用了一个特征(或者一个特征的盒子)

为了让您的程序能够按照您最初编写的方式编译和运行,您只需要实现trait for box,我们也可以执行引用:

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() }    
}
impl HasArea for Box
其中T:HasArea
{
fn区域(&self)->f64{(**self.area()}
}
impl f64{(**self).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![Box::new(c), Box::new(s)];

    for x in vec {
        print_area(x)
    }
}
fn main(){
设c=圆{
x:0.0f64,
y:0.0f64,
半径:1.0f64,
};
让s=平方{
x:0.0f64,
y:0.0f64,
侧面:1.0f64,
};
打印区域(&c);
打印区域(&s);
让vec:vec=vec![Box::new(c),Box::new(s)];
对于向量中的x{
打印区域(x)
}
}
这里,我们将
c
s
的引用传递到
print\u区域
,以避免