在Rust中推广迭代方法
假设我有一些自定义的Foos集合:
struct Bar {}
struct Foo {
bar: Bar
}
struct SubList {
contents: Vec<Foo>,
}
并假设我也有一个sSuperList的自定义集合SubList:
struct SuperList {
contents: Vec<SubList>,
}
SubList并且SuperList每个都提供一个方法bars:
impl SubList {
fn bars(&self) -> impl Iterator<Item = &Bar> + '_ {
self.contents.iter().map(|x| &x.bar)
}
}
impl SuperList {
fn bars(&self) -> impl Iterator<Item = &Bar> + '_ {
self.contents.iter().flat_map(|x| x.items())
}
}
我想定义一个提供 method 的特征items,并在SubListand上实现该特征,SuperList这样SubList::items就等价于SubList::bars并且SuperList::items等价于SuperList::bars,这样我就可以做到这一点:
fn do_it<T: Buz<Bar>>(buz: &T) {
for item in buz.items() {
println!("yay!")
}
}
fn main() {
let foos = vec![Foo{ bar: Bar{} }];
let sublist = SubList{ contents: foos };
do_it(&sublist);
let superlist = SuperList{ contents: vec![sublist] };
do_it(&superlist);
}
我可以用动态调度做我想做的事:
trait Buz<T> {
fn items(&self) -> Box<dyn Iterator<Item = &T> + '_>;
}
impl Buz<Bar> for SubList {
fn items(&self) -> Box<dyn Iterator<Item = &Bar> + '_> {
SubList::bars(self)
}
}
impl Buz<Bar> for SuperList {
fn items(&self) -> Box<dyn Iterator<Item = &Bar> + '_> {
SuperList::bars(self)
}
}
但是,以下方法不起作用:
trait Baz<T> {
fn items(&self) -> impl Iterator<Item = &T> + '_;
}
impl Baz<Bar> for SubList {
fn items(&self) -> impl Iterator<Item = &Bar> + '_ {
SubList::bars(self)
}
}
impl Baz<Bar> for SuperList {
fn items(&self) -> impl Iterator<Item = &Bar> + '_ {
SuperList::bars(self)
}
}
(error[E0562]: `impl Trait` not allowed outside of function and inherent method return types)
这是我迄今为止尝试过的内容的游乐场链接
我如何定义一个特点Baz它提供了一个items在方法抽象bars的方法SubList和SuperList不使用动态分配?