rust - 实现并使用另一个特征的特征

标签 rust

我有一个想要用作迭代器的特性,并且我希望迭代器实现能够使用自定义特性实现。在 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())
    }
}

最佳答案

理想情况下,您将为实现Iterator的任何内容编写毯子式Generator实现,例如:

impl<T: Generator> Iterator for T {
    // ...
}
但是Rust不会接受这一点,因为您无法提供您自己的 crate 中未定义的特征的全面实现-这会违反orphan rule
但是,没有什么可以阻止您将任何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()
}
playground中的可运行代码。

关于rust - 实现并使用另一个特征的特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65065190/

相关文章:

rust - 如何连接到 Rust 中的 systemd D-Bus org.freedesktop.timedate1 端点?

rust - 如何检查用户输入的变量是数字(int,float)?

rust - 有没有办法制作包含自身矢量的特征?

json - 如何在 Rust 中反序列化 JSON 中的 &str 结构字段

rust - 如何有条件地链接迭代器?

python - 从 Python 调用 Rust 时出错

rust - 模式匹配如何与 Rust 中的 ref 一起工作?

rust - 如何为结构的可变引用中的字段换入新值?

rust - 在 Rust 中使用本地可变副本迭代数组

performance - HashMap 和 Vec 之间的内存高效转换