具有“自我quot”的功能的特征因为不能将参数制成对象
我正在尝试建立一个实体组件系统,以作为我学习生锈的旅程的一部分。 我知道每个组件在哪里具有静态ID,并且对象将具有其中包含的组件的缩放图(每种类型的一个组件的限制)。
这是对象本身:
pub struct Object {
// TODO : components !
components: HashMap<i32, Box<dyn Component>>
}
impl Object {
pub fn add_component<C: Component>(&self) {
self.components.insert(C::id(), Box::new(C::new()));
}
pub fn get_component<C: Component>(&self) -> Option<&C> {
return self.components.get(C::id())
}
}
这是我的组件特征:
pub trait Component {
fn id() -> i32 {
// one must ensure this returns different id for every component
return 0;
}
fn new<C: Component>() -> C;
fn require_rendering(&self) -> bool {
return false;
}
fn some_function_on_component(&mut self) {
// do something on the component
}
}
不幸的是,我得到此错误:
“这个特征不能成为对象...
...因为关联的函数 id
没有 self
参数“
谁能解释为什么这不起作用,以及如何处理它?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
通过遵循编译器消息,大多数可以很容易地解决。
我在试图将代码编译时遇到的最大障碍是降低
box&lt; dyn&gt;
回到其原始类型。那是我的尝试,我不知道它是否最终是否确实在做某事,但至少它编译了:)
我已经完成的事情:
self:sized
id()和
new()
。这两个都是性状函数,因此必须在运行时解决。解决类型的步骤需要称为“ vtable”的东西,这仅存在于实际尺寸的类型上。 (至少这是我对问题的理解)new
上的self
替换通用参数,因为这是您实际上想要的。mut
添加到self
inadd_component
id> id()
的默认实现,以实际强制实现结构来覆盖其降低get_component
的&amp; dyn Component
,基于此帖子。当然,可能有不同的解决方案,我只是选择了一个,因为我不想做任何进一步的研究:)我没有解决您目前只从
get_component 。这可能是您将要解决的下一步。
总而言之,这是带有“名称”和“年龄”组件的代码的最小工作示例,只是为了证明您的方法是可行的:
Most of those are fairly easily fixable by following the compiler messages.
The biggest hurdle I came across while trying to get your code to compile is to downcast the
Box<dyn>
back to its original type.That's my attempt, I have no idea if it actually does something in the end, but at least it compiles :)
Things I've done:
Self: Sized
toid()
andnew()
. Both of those are trait functions and therefore have to be resolved at runtime. The step of resolving the type requires something called a "vtable", which only exists on types that actually have a size. (that's at least my understanding of the problem)new
withSelf
, as this is what you probably actually want.mut
toself
inadd_component
id()
to actually force implementing structs to overwrite it&dyn Component
to the actual component type inget_component
, based on this post. Of course there are probably different solutions, I just picked that one because I didn't feel like doing any further research :)I didn't solve the problem that you currently only get non-mutable objects out of
get_component
. This will probably be the next thing you will tackle.All in all, here is a minimal working example of your code with a "Name" and an "Age" component, just to demonstrate that your approach is feasible:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=5d22b64ab924394606a07a043594f608