我在一个预先存在的项目工作,需要添加一个字段结构Message
这是一个Box <dyn Any>
。
对于这个项目,将Box<dyn Any>
转换为枚举是不可能的。
pub struct Message<PB: ProtocolBehavior> {
/* */
pub info: Box<dyn Any>,
}
字符串
不幸的是,Message
需要是(反)序列化的,并实现哈希,克隆,调试,显示(列表还在继续);因此,字段info
也是如此。
我想出来的是创建一个新的trait AnySerializable
。我让它实现了所有必要的特性。(感谢dtolnay's typetag crate,我能够使这个新的trait序列化)
#[typetag::serde(tag = "type")]
pub trait AnySerializable: Any + core::fmt::Debug + std::fmt::Display + DynClone + DynHash {}
型
然后我修改了Message
的字段info
。
pub struct Message<PB: ProtocolBehavior> {
/* */
pub info: Box<dyn AnySerializable>,
}
型
但是,我需要能够将信息转换为Box<dyn Any>
。
下面的代码给了我一个错误,因为返回类型不匹配。
impl Message {
pub fn get_info(&self) -> Box<dyn Any> {
self.info
}
}
型
然后我尝试在trait AnySerializable
中添加一个方法
#[typetag::serde(tag = "type")]
pub trait AnySerializable: Any + core::fmt::Debug + std::fmt::Display + DynClone + DynHash {
fn as_any(&self) -> dyn Any;
}
型
沿着用于Message
的该方法。
impl Message {
pub fn get_info(&self) -> Box<dyn Any> {
Box::new(self.info.clone().as_ref().as_any())
}
}
型
但是我不能装箱dyn Any
,因为在编译时它的大小是未知的。
但我想做这样的事。有没有一种方法可以做到这一点,可能是不安全的Rust?
我尝试在项目中将任何出现的Any
替换为AnySerializable
,但我得到了额外的错误,这些错误似乎非常复杂。如果我不能优雅地得到一个Box<dyn Any>
,我会调查他们。
2条答案
按热度按时间f4t66c6m1#
你cannot currently upcast在稳定生 rust ,甚至不使用不安全的[0][1]。注意:上转换是将子trait对象(
AnySerializable
)转换为它的supertrait对象(Any
)。恐怕对您来说最好的方法是将许多
Any
的出现改为AnySerializable
。在nightly rust中有一个特性,它允许在最小的代码更改下工作,但根据它的进展,我不希望它在接下来的几个版本中稳定下来。字符串
[0][Why doesn't Rust support trait object upcasting?](https://stackoverflow.com/questions/28632968/why-doesnt-rust-support-trait-object-upcasting)的
[1][Is it possible to cast a trait object to another trait object?](https://stackoverflow.com/questions/55895583/is-it-possible-to-cast-a-trait-object-to-another-trait-object)的
yi0zb3m42#
我找到了这个板条箱,它做的正是我想做的!
它允许向下转换为
Box<dyn Any>
。