当前位置: 首页 > 知识库问答 >
问题:

如何对多态向量中包含的元素进行拆箱?

孟胤
2023-03-14

看了这个“属于某个特质的对象的向量”的回答,看起来Rust是做自动拆箱的,是这样的吗?

我的代码无法编译,我不明白该答案的代码如何编译。

什么是解除包含装箱特征的多态向量元素装箱的正确方法?

我已经阅读了 Rust by Example 和 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)
    }
}

我的错误是:

   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`

共有3个答案

南门志
2023-03-14

阅读后https://stackoverflow.com/a/25819164/129805看起来铁锈能自动拆箱。是这样吗?

没有您想象的那么自动。事实上,您正在寻找unbox方法,而Box

我冒昧地修复了mainprint_area以使其工作。向量也被错误地声明为不可变的。

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)
    }
}

郑功
2023-03-14

回答你的直接问题:

如何对多态向量中包含的元素进行拆箱?

你不能。一旦某些东西被装箱并删除了具体类型,就是这样。一个盒子

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

特征绑定<代码>框

那是因为对一个特征(或一个特征框)的引用并没有实现那个特征!

为了让您的程序按照您最初编写的方式编译和运行,您只需要为框实现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() }    
}

这允许您的固定干线运行:

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)
    }
}

在这里,我们将<code>c</code>和<code>s</code>的引用传递给<code>print_area</code>,以避免所有权转移。我们还使用向量机 宏以更少的时间构造向量。

百里鸿祯
2023-03-14

您可以像< code>print_area(*x)一样取消对它的引用,但是由于其他原因,它不起作用:为< code>print_area参数绑定了< code > size 。你的函数需要知道它的参数的大小。

你的代码中还有其他问题:你试图推入一个不可变的向量,你试图框移动的值。这些在print_area()中使用后被移动。

我的观点是,让<code>print_area</code>成为一种采用不可变引用的方法会更容易。这将按您的预期工作。

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();
    }
}
 类似资料:
  • 问题内容: 在我的程序中,创建了一个固定长度[7]个对象的数组,每个对象都是一个包含3 ,an 和an的类。这些值是从.txt文件中读取的,并基于的值添加到数组的特定索引中。.txt文件中的条目较少,然后数组中存在索引,因此该数组最终看起来像这样: 后来在节目中,我需要的基础上平均的排序的数组中。我有一个工作方法返回这个,但是当我尝试使用数组进行排序和我开始得到这些错误的一个长长的清单: 我的方法

  • 问题内容: 我有一个数组,如: 谁能建议一种基于datetime元素对此进行排序/排序的方法? 问题答案: 使用和自定义比较功能: 编辑 :您的数据组织在一个数组的数组中。为了更好地区分这些数据,我们将其称为内部数组(数据)记录,以便您的数据实际上是一个记录数组。 会一次将其中两个记录传递给给定的比较函数。 然后将每个记录的字段提取为UNIX时间戳(整数),并返回差值,以便结果将是两个日期相等,如

  • 问题内容: By Company   我需要捕获上述元素的xpath。我尝试了以下替代方法,但在Chrome中似乎没有任何效果。您能否建议其他选择。 问题答案: 要查找元素: 您可以使用以下xpath之一: 使用: 使用: 但是,理想情况下,您可能希望避免使用 NO-BREAK SPACE 字符,并使用以下任一解决方案: 使用: 使用: 参考 您可以在以下位置找到相关的详细讨论: 使用XPATH搜

  • 本文向大家介绍如何在R中按降序对包含单个子元素的列表进行排序?,包括了如何在R中按降序对包含单个子元素的列表进行排序?的使用技巧和注意事项,需要的朋友参考一下 就像列表可以具有多个元素一样,列表的元素可以具有多个子元素,并且这些元素的大小也可以变化,因此具有单个子元素的列表也是可能的。如果我们有这种类型的列表,则可以使用order函数以递减的顺序对该列表进行排序,但是我们还需要取消列出那些元素。

  • 我要求用户在控制台写四个数字,每个数字用连字符分隔。然后我将它们拆分,这将自动创建一个列表,并将其转换为int。但我不知道用户输入了多少数字。 如何检查if方法中这个列表包含多少元素?我需要这样的东西: 我不需要建议来重建我的代码,我需要知道我是否可以检查它或不。

  • 本文向大家介绍C#中获取BitArray中包含的元素数量,包括了C#中获取BitArray中包含的元素数量的使用技巧和注意事项,需要的朋友参考一下 要获取BitArray中包含的元素数量,代码如下- 示例 输出结果 这将产生以下输出- 示例 现在让我们来看另一个示例- 输出结果 这将产生以下输出-