英文:
Upcasting an `Arc<dyn Trait>` to an `Arc<dyn Any>`?
问题
假设我有一个类型为 `Asset` 的特性对象,它存储在一个 `Arc` 中,并且我想将它转换为一个 `Arc<dyn Any>` 以便之后进行下转型。
有没有安全的方法可以做到这一点?我尝试了使用 [`as-any`](https://docs.rs/as-any/latest/as_any/) crate 的这种(不安全的)策略,但似乎它会破坏类型信息,因为我无法将得到的 `Arc<dyn Any>` 转换回它的基本类型:
let res: Box<dyn Asset> = thing_that_returns_dyn_asset();
let res: Arc<dyn Asset> = Arc::from(res);
// 不安全:将 Arc<dyn Asset> 转换为 Arc<dyn Any>。
let res : Arc<dyn Any> = unsafe {
Arc::from_raw(Arc::into_raw(res).as_any())
};
但似乎并不起作用。我知道目前有一个实验性的功能可以向上转型对象,但那似乎并没有帮助。
英文:
Suppose I have a trait object of type Asset
, which is stored in an Arc
, and I want to convert it to an Arc<dyn Any>
to facilitate later downcasting.
Is there any safe way to do this? I have tried this (unsafe) strategy using the as-any
crate, but it seems to break the type information as I can't downcast
the resulting Arc<dyn Any>
to its base type:
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())
};
But it does not seem to work. I'm aware that there's a currently experimental feature to upcast objects, but that doesn't seem to help.
答案1
得分: 1
The easiest way is to add a method that casts from Arc<Asset>
to Arc<dyn Any>
. Following as-any
, we can do that in a custom trait and have a blanket implementation for it:
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();
英文:
The easiest way is to add a method that casts from Arc<Asset>
to Arc<dyn Any>
. Following as-any
, we can do that in a custom trait and have a blanket implementation for it:
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();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论