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

将实现特征的数据存储在向量中

司空鸿熙
2023-03-14

我对 Rust 和系统语言非常陌生。我目前正在与 Rust 一起探索这门语言。我有一个我自己无法解决的问题。我想我已经理解了问题所在。

我不想在vector中存储实现< code>trait BaseStuff的对象。在Rust对我来说不是一个简单的任务:-)。

这是我的示例代码,不会编译。

trait BaseStuff {}

struct MyStuff {
    value: i32,
}

struct AwesomeStuff {
    value: f32,
    text: String,
}

impl BaseStuff for MyStuff {}

impl BaseStuff for AwesomeStuff {}

struct Holder {
    stuff: Vec<BaseStuff>,
}

impl Holder {
    fn register(&mut self, data: impl BaseStuff) {
        self.stuff.push(data);
    }
}

fn main() {
    let my_stuff = MyStuff { value: 100 };

    let awesome_stuff = AwesomeStuff {
        value: 100.0,
        text: String::from("I'm so awesome!"),
    };

    let mut holder = Holder { stuff: vec![] };

    holder.register(my_stuff);
}

错误[E0277]:类型(dyn BaseStuff'静态)的值的大小在编译时无法知道-

错误:由于以前的错误而中止

有关此错误的详细信息,请尝试rustc--解释E0277。错误:无法编译playground

编译器的信息是清楚的,我理解这个信息。我可以在任何我想要的结构中实现trait BaseStuff,所以不清楚它的大小。顺便说一句,这个链接没有帮助,因为它指向了过时的网站...

字符串的大小也是未知的,但是字符串实现了trait<code>std::marker::Sized</code>这就是为什么<code>Vec

在我读过的rust书中,对于大小未知的数据类型,我必须将这些数据存储在堆中,而不是堆栈中。我将代码修改如下。

struct Holder {
    stuff: Vec<Box<BaseStuff>>,
}

impl Holder {
    fn register(&mut self, data: impl BaseStuff) {
        self.stuff.push(Box::new(data));
    }
}

现在我遇到了一个新的编译器问题:

错误[E0310]:参数类型impl-BaseStuff可能寿命不够长--

错误:由于以前的错误而中止

有关此错误的更多信息,请尝试rustc--explain E0310。错误:无法编译游戏场

而且知道我出去了...我在书中读到了关于生命的文章,并用“a here”“a”在任何组合中更改了我的代码,但没有运气......我不想写下我尝试过的任何生命周期定义组合。我不明白为什么我需要终身定义。所有权在任何步骤中移动,因此为了我的理解,可以清楚地看到Holder结构是所有数据的所有者。是吗?

如何更正我的代码以进行编译?

谢谢你的帮助。

共有1个答案

水睿
2023-03-14

你几乎明白了-这里的问题是实现BaseStuff的类型可能是引用(例如impl BaseStuff for

解决此问题的方法是添加一个约束,使对象具有'静态生命周期,这意味着它将是值类型或静态引用。您可以将此约束应用于trait或接受trait的方法,具体取决于您的用例。

将约束应用于特征:

trait BaseStuff: 'static {}

将约束应用于方法:

impl Holder {
    fn register(&mut self, data: impl BaseStuff + 'static) {
        self.stuff.push(Box::new(data));
    }
}

如果您将'静态约束添加到方法中,我建议还将其添加到Vec以避免丢失类型信息,如下所示:

struct Holder {
    stuff: Vec<Box<dyn BaseStuff + 'static>>,
}

 类似资料:
  • 我有一个设计问题,当使用类似的东西时: 我认为应该有一些更好的方法来实现这种参数化的特性。 我在std中没有找到好的示例(例如,在具有类似的关联类型的traits中没有实现)?

  • 问题内容: 我想知道如何在数据库中最好地实现“ 观看次数最多 ”的功能(例如youtube)。 让我来解释一下“ 最多观看 ”功能更好一点: 基本上,我想列出从这天/周/月访问最多的网页/视频/等,见 http://www.youtube.com/charts/videos_views为一个例子。 因此,我想知道如何最好地实现此功能,因为我可以想到许多实现此功能的方法,但是所有方法都具有+和-的含

  • (这是我第二次尝试追踪我的确切问题。查看编辑历史记录) 我有一个简单的通用特性和两种不同的实现: 我现在想要一个包含两个实现元素的向量。正如我在这里学到的,我做: 但是编译器不同意: 一方面,这是有道理的。另一方面,我应该为写什么?我希望它是通用的,所以我不能简单地在那里放或。我可以做

  • 我正在尝试创建一个特征对象的向量,但我得到了类型不匹配。我还尝试使用代替for循环,但遇到了同样的问题。这是我真实代码的最小版本,我意识到这个例子不需要使用特征对象,但我的真实代码需要,因为列表中除了之外还有其他类型,它们也实现了。如何使用正确的类型创建以便将其传递给?

  • 我希望编写一个模板函数来接受Eigen::vectrox*(float/int/double)和std::vector 如何声明模板?下面的方法不起作用。 其基本原理是不编写单独的函数所有不同的组合。