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