![](/img/trans.png)
[英]Why are iterator items which are references not cast to a trait object reference?
[英]How can I transform an iterator trait object of concrete types into an iterator trait object of trait objects?
我有一個特征,其中包含一個函數,該函數返回對另一個特征的引用的迭代器,例如:
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
類型(具體類型而不是trait類型)的迭代器-如何解決?
默認情況下,特征對象以'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 _))
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.