我有一个特征,其中包含一个函数,用于返回对另一个特征的引用的迭代器,例如:
pub trait ParentInterface {
fn children<'a>(&'a self) -> Box<dyn Iterator<Item = &'a ChildInterface>>;
}
pub trait ChildInterface {
fn some_method(&self) -> bool;
}
当为存储具体值向量的具体类型实现此特征时,如何返回正确类型的迭代器?
pub struct ConcreteParent {
my_children: Vec<ConcreteChild>,
}
pub struct ConcreteChild {
my_value: bool,
}
impl ParentInterface for ConcreteParent {
fn children<'a>(&'a self) -> Box<dyn Iterator<Item = &'a ChildInterface>> {
Box::new(self.my_children.iter()) // Compiler error!
}
}
impl ChildInterface for ConcreteChild {
fn some_method(&self) -> bool {
self.my_value
}
}
上面的示例会产生 Rust 2018 的编译器错误:
error[E0271]: type mismatch resolving `<std::slice::Iter<'_, ConcreteChild> as std::iter::Iterator>::Item == &dyn ChildInterface`
--> src/lib.rs:19:9
|
19 | Box::new(self.my_children.iter()) // Compiler error!
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `ConcreteChild`, found trait ChildInterface
|
= note: expected type `&ConcreteChild`
found type `&dyn ChildInterface`
= note: required for the cast to the object type `dyn std::iter::Iterator<Item = &dyn ChildInterface>`
我假设 my_children.iter()
返回一个具有错误 Item
类型(具体类型而不是特征类型)的迭代器 - 如何解决这个问题?
最佳答案
默认情况下,特征对象以'static
为边界。您必须指定生命周期 'a
然后才能正确映射迭代器 ( source ):
pub trait ParentInterface {
fn children<'a>(&'a self) -> Box<dyn Iterator<Item = &'a dyn ChildInterface> + 'a>;
}
pub trait ChildInterface {
fn some_method(&self) -> bool;
}
pub struct ConcreteParent {
my_children: Vec<ConcreteChild>,
}
pub struct ConcreteChild {
my_value: bool,
}
impl ParentInterface for ConcreteParent {
fn children<'a>(&'a self) -> Box<dyn Iterator<Item = &'a dyn ChildInterface> + 'a> {
Box::new(self.my_children.iter().map(|c| c as &'a dyn ChildInterface))
}
}
impl ChildInterface for ConcreteChild {
fn some_method(&self) -> bool {
self.my_value
}
}
注意更改:
迭代器的引用边界是
'a
,就像项目一样:dyn Iterator</*...*/> + 'a
每个具体类型都映射到一个特征对象:
.map(|c| c as &'a dyn ChildInterface)
请注意,您可以简化符号以使推理正常进行:
.map(|c| c as _)
您可以使用生命周期'_
进一步简化:
pub trait ParentInterface {
fn children(&self) -> Box<dyn Iterator<Item = &dyn ChildInterface> + '_>;
}
// ...
impl ParentInterface for ConcreteParent {
fn children(&self) -> Box<dyn Iterator<Item = &dyn ChildInterface> + '_> {
Box::new(self.my_children.iter().map(|c| c as _))
}
}
关于reference - 如何将具体类型的迭代器特征对象转换为特征对象的迭代器特征对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56496044/