[英]How to make type-erased version of a trait with associated type?
Say there is a collection trait that has an associated type for its items:假设有一个集合特征,其项具有关联类型:
trait CollectionItem {
// ...
}
trait Collection {
type Item: CollectionItem;
fn get(&self, index: usize) -> Self::Item;
// ...
}
Can I somehow type-erase this into a type that uses dynamic dispatch for both the Collection
and the CollectionItem
trait?我能以某种方式将其类型擦除为对Collection
和CollectionItem
特征使用动态分派的类型吗? ie wrap it into something like the following:即把它包装成类似下面的东西:
struct DynCollection(Box<dyn Collection<Item=Box<dyn CollectionItem>>>);
impl DynCollection {
fn get(&self, index: usize) -> Box<dyn CollectionItem> {
// ... what to do here?
}
}
impl <C: Collection> From<C> for DynCollection {
fn from(c: C) -> Self {
// ... what to do here?
}
}
You can add a private, type-erased helper trait:您可以添加一个私有的、类型擦除的辅助特征:
trait DynCollectionCore {
fn get_dyn(&self, index: usize) -> Box<dyn CollectionItem>;
}
impl<C> DynCollectionCore for C
where
C: ?Sized + Collection,
C::Item: 'static,
{
fn get_dyn(&self, index: usize) -> Box<dyn CollectionItem> {
Box::new(self.get(index))
}
}
Then use this to build a wrapper type:然后使用它来构建包装器类型:
struct DynCollection(Box<dyn DynCollectionCore>);
impl DynCollection {
fn new<C>(inner: C) -> Self
where
C: Collection + 'static,
C::Item: 'static,
{
Self(Box::new(inner))
}
}
impl Collection for DynCollection {
type Item = Box<dyn CollectionItem>;
fn get(&self, index: usize) -> Box<dyn CollectionItem> {
self.0.get_dyn(index)
}
}
// note: something like this is also needed for `Box<dyn CollectionItem>:
// CollectionItem` to be satisfied
impl<T: ?Sized + CollectionItem> CollectionItem for Box<T> {
// ...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.