Rust Trait 对象转换 [英] Rust Trait object conversion
问题描述
由于此错误的两个实例,以下代码将无法编译:
The following code won't compile due to two instances of this error:
error[E0277]: trait bound Self: std::marker::Sized
不满足
error[E0277]: the trait bound
Self: std::marker::Sized
is not satisfied
我不明白为什么在这种情况下需要 Sized
因为 &self
和 &Any
都是指针和操作不需要知道实现 trait 的结构的大小,它只需要知道指针本身和它正在转换的类型,因为 &self
是通用的当在 trait 中实现时.
I don't understand why Sized
is required in this instance as both &self
and &Any
are pointers and the operation does not require knowledge of the size of the structure that implements the trait, it only requires knowledge of the pointer itself and the type it is converting from and to, which it will have because &self
is generic when implemented inside a trait.
我认为这可能是编译器强制执行不必要约束的一个实例,我已经考虑向 rust-lang GitHub 存储库提交问题,但我想我应该在我走之前看看这里是否有人知道我不知道的事情提出问题.
I think this may be an instance of the compiler enforcing unnecessary constraints and I've considered filing an issue with the rust-lang GitHub repo but I figured I should probably see if someone here knows something I don't before I go file an issue.
use std::any::Any;
trait Component: Any {
fn as_any(&self) -> &Any {
self
}
fn as_any_mut(&mut self) -> &mut Any {
self
}
}
替代方法是为实现此特征的结构体制作 as_any()
和 as_any_mut()
所需的函数,但对于这些结构体,实现始终是与此处显示的每个字符完全一样,从而产生多个相同样板代码的实例.
The alternative to this is to make as_any()
and as_any_mut()
required functions for the structs that implement this trait, but for those structures the implementation would always be exactly as displayed here down to each individual character, resulting in several instances of identical boilerplate code.
推荐答案
我发现我认为是一个很棒的解决方案,它不需要新的编译器功能.
I found what I consider to be a great solution that didn't require new compiler features.
pub trait Component {
// ...
}
pub trait ComponentAny: Component + Any {
fn as_any(&self) -> &Any;
fn as_any_mut(&mut self) -> &mut Any;
}
impl<T> ComponentAny for T
where T: Component + Any
{
fn as_any(&self) -> &Any {
self
}
fn as_any_mut(&mut self) -> &mut Any {
self
}
}
从这里开始,我只是将所有 API 更改为接受 ComponentAny
而不是 Component
.因为 Any
是为任何 'static
类型自动实现的,所以 ComponentAny
现在可以为任何 'static
类型自动实现实现 Component
.感谢 有没有办法结合多个特征来定义一个新的特征?对于这个想法.
From here, I just change all my APIs to accept ComponentAny
instead of Component
. Because Any
is automatically implemented for any 'static
type, ComponentAny
is now automatically implemented for any 'static
type that implements Component
. Thanks to Is there a way to combine multiple traits in order to define a new trait? for the idea.
这篇关于Rust Trait 对象转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!