簡體   English   中英

為另一個特征實現和使用特征

[英]Implement and consume trait for another trait

我有一個特征,我希望能夠將其用作迭代器,並且我希望迭代器實現利用自定義特征實現。 在 rust 中是否可能出現以下情況,其中兩個特征實現相互依賴,還是推薦使用不同的架構?

trait Generator {
    fn generate(&self) -> String;

    fn generate_many(&self, count: usize) -> Vec<String> {
        self.take(count).collect()
    }
}

impl Iterator for dyn Generator {
    type Item = String;

    fn next(&mut self) -> Option<Self::Item> {
        Some(self.generate())
    }
}

編輯:
嘗試超特質

trait Generator: Iterator {
    type Item = String;

    fn generate(&self) -> String;

    fn generate_many(&self, count: usize) -> Vec<String> {
        self.take(count).collect()
    }

    fn next(&mut self) -> Option<Self::Item> {
        Some(self.generate())
    }
}

理想情況下,您應該為實現Generator的任何東西編寫Iterator的全面實現,例如:

impl<T: Generator> Iterator for T {
    // ...
}

但是 Rust 不會接受,因為你不能提供你沒有在你自己的 crate 中定義的特征的全面實現——這會違反孤兒規則

但是,沒有什么能阻止您將任何Generator包裝在您自己的實現Iterator的泛型類型中:

struct Wrapped<G: Generator>(G);

impl<G: Generator> Iterator for Wrapped<G> {
   // ...
}

這並不違反孤兒規則,因為一攬子實現僅適用於我們在本地定義的Wrapped類型的變體,並且T本身保持不變。 它是零開銷,因為Wrapped<G>只是直接存儲G ,無論G是什么,不引入分配或間接。

最后,您甚至不需要實現上述結構,您可以將包裝留給標准庫提供的iter::from_fn()助手:

fn iter<G>(g: &G) -> impl Iterator<Item = String> + '_
where
    G: Generator + ?Sized,
{
    std::iter::from_fn(move || Some(g.generate()))
}

然后你可以使用iter()來實現generate_many()

fn generate_many(&self, count: usize) -> Vec<String> {
    iter(self).take(count).collect()
}

操場上的可運行代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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