假设我有一个
Asset
类型的trait对象,存储在一个Arc
中,我想把它转换成一个Arc<dyn Any>
,方便后面的向下转型。
有什么安全的方法可以做到这一点吗?我已经尝试过这种(不安全的)策略,但它似乎破坏了类型信息,因为我不能
downcast
结果Arc<dyn Any>
到它的基本类型:
let res: Box<dyn Asset> = thing_that_returns_dyn_asset();
let res: Arc<dyn Asset> = Arc::from(res);
// Unsafe: Cast an Arc<dyn Asset> to an Arc<dyn Any>.
let res : Arc<dyn Any> = unsafe {
Arc::from_raw(Arc::into_raw(res).as_any())
};
但是好像不行。我知道目前有一个向上转换对象的实验性功能,但这似乎没有帮助。
最简单的方法是添加一个从
Arc<Asset>
转换为Arc<dyn Any>
的方法。在 as-any
之后,我们可以在自定义特征中做到这一点,并对其进行全面实施:
pub trait AsAnyArc {
fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any>;
}
impl<T: 'static> AsAnyArc for T {
fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any> { self }
}
pub trait Asset: AsAnyArc { ... }
let res: Box<dyn Asset> = thing_that_returns_dyn_asset();
let res: Arc<dyn Asset> = Arc::from(res);
let res: Arc<dyn Any> = res.as_any_arc();