我正在try 在具有相同特征的盒装特征对象上实现特征.我以前做过这样的特征,它的方法是&self
,这很好用,但不是self
.
// The purpose of this trait is to allow for converting any kind of "group" which might eg be nested tuples like below, and convert it into a flat Vec of Items
trait Group {
fn into_vec(self) -> Vec<Box<dyn Item>>;
}
trait Item: Group {}
// Foo is an Item an can also be made into a group
struct Foo {}
impl Item for Foo {}
impl Group for Foo {
fn into_vec(self) -> Vec<Box<dyn Item>> {
vec![Box::new(self)]
}
}
// impl Group for data structures which contain items or other nested structures containing items
impl<A: Group, B: Group> Group for (A, B) {
fn into_vec(self) -> Vec<Box<dyn Item>> {
let mut new_vec = Vec::new();
new_vec.extend(self.0.into_vec().into_iter());
new_vec.extend(self.1.into_vec().into_iter());
new_vec
}
}
// Can create a single group fine
fn get_group() -> impl Group {
(Foo {}, (Foo {}, Foo {}))
}
// Sometimes I might want to return different groups from different braches so need to box them
// However I'm not sure how to implement this. self.into_vec() is an ifinite recursion, and can't deref self either.
impl Group for Box<dyn Group> {
fn into_vec(self) -> Vec<Box<dyn Item>> {
(*self).into_vec()
}
}
fn get_group_conditonal(condition: bool) -> impl Group {
if condition {
Box::new((Foo {}, (Foo {}, Foo {}))) as Box<dyn Group>
} else {
Box::new(Foo {}) as Box<dyn Group>
}
}
我意识到,在这个特定的示例中,我可以将fn get_*()
个函数更改为返回Box<dyn Group>
来解决问题.然而,API的其余部分具有将输入作为impl Group
的函数.如果我不能impl Group for Box<dyn Group>
,那么这将进入API的其余部分,并要求所有函数只接受盒装特征对象作为输入,而不是impl Group
,如果可能的话,我想避免这种情况.