我对 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结构是所有数据的所有者。是吗?
如何更正我的代码以进行编译?
谢谢你的帮助。
你几乎明白了-这里的问题是实现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 如何声明模板?下面的方法不起作用。 其基本原理是不编写单独的函数所有不同的组合。