gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 11:41:31 27 4
gpt4 key购买 nike

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

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com