我有一个迭代器特征,它使用通用关联类型来允许返回值引用迭代器拥有的数据:
pub trait MyIterator {
type T<'a>
where
Self: 'a;
fn next<'b>(&'b mut self) -> Option<Self::T<'b>>;
}
一个示例实现如下所示:
struct FooIterator<'counter> {
data: Vec<String>,
counter: &'counter AtomicU32,
index: usize
}
impl<'counter> MyIterator for FooIterator<'counter> {
type T<'d> = &'d str
where
Self: 'd;
fn next<'e>(&'e mut self) -> Option<Self::T<'e>> {
self.counter.fetch_add(1, Ordering::SeqCst);
self.index += 1;
Some(&self.data[self.index])
}
}
现在,我想要一个返回 impl MyIterator
对象而不公开实现类型的工厂。但是,我不知道如何写生命周期。
我的第一次尝试是:
struct Factory {
data: Vec<String>,
counter: AtomicU32,
}
impl Factory {
fn new() -> Self {
Factory {
data: vec!["a".to_string(), "b".to_string(), "c".to_string(), "d".to_string()],
counter: AtomicU32::new(0),
}
}
fn create<'f>(&'f self) -> impl MyIterator<T<'_> = &'_ str> {
FooIterator {
data: self.data.clone(),
counter: &self.counter,
index: 0
}
}
}
但是,这会在尝试使用返回的迭代器时导致双重借用错误,如下所示:https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=6490de8f21539537764d8f628454c5c1
接下来我尝试使用 Higher Rank Trait Bound,这似乎应该有效,但我无法编译以下内容,因为 'g
似乎不在范围内where 子句 ( https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=beb46184de6f96bf83b64e838da4a335 ):
fn create<'f>(&'f self) -> impl for<'g> MyIterator<T<'g> = &'g str> + 'f where 'f: 'g {
FooIterator {
data: self.data.clone(),
counter: &self.counter,
index: 0
}
}
没有返回 impl MyIterator
代码工作正常,但我不想公开 FooIterator
类型。看到这个 Playground :https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=2c595c136077791a692ea6e0a41c057c
最佳答案
您的问题出在 MyIterator
定义中,因为 next
函数对自身进行可变借用并返回与该可变借用一样长的东西,即不是您对迭代器的期望。
这很微妙,因为它不会使代码变得不可靠,它只会强制执行过多的约束,这反过来又导致无法在不出错的情况下使用该特征。对 MyIterator
特征中的生命周期进行简单的重构使其工作。 See the playground .
关于rust - 我如何绑定(bind) Higher Rank Trait Bound 生命周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72065426/