簡體   English   中英

如何將具體類型的迭代器特征對象轉換為特征對象的迭代器特征對象?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM