Gor*_*ood 1 iterator lifetime rust borrow-checker
进一步IntoIterator
按照Rust的书实现包装矢量的示例,我还尝试根据以下代码(Playground链接)实现IntoIterator以引用包装器:
struct VecWrapper(Vec<i32>);
impl VecWrapper {
fn iter(&'static self) -> Iter {
Iter(Box::new(self.0.iter()))
}
}
struct Iter(Box<Iterator<Item = &'static i32>>);
impl Iterator for Iter {
type Item = &'static i32;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}
impl IntoIterator for &'static VecWrapper {
type Item = &'static i32;
type IntoIter = Iter;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
fn main() {
// let test = vec![1, 2, 3]; // obviously, works
let test = VecWrapper(vec![1, 2, 3]); // not working
for v in &test {
println!("{}", v);
}
}
Run Code Online (Sandbox Code Playgroud)
尽管实现可以编译,但尝试使用它main
不会出现以下错误:
struct VecWrapper(Vec<i32>);
impl VecWrapper {
fn iter(&'static self) -> Iter {
Iter(Box::new(self.0.iter()))
}
}
struct Iter(Box<Iterator<Item = &'static i32>>);
impl Iterator for Iter {
type Item = &'static i32;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}
impl IntoIterator for &'static VecWrapper {
type Item = &'static i32;
type IntoIter = Iter;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
fn main() {
// let test = vec![1, 2, 3]; // obviously, works
let test = VecWrapper(vec![1, 2, 3]); // not working
for v in &test {
println!("{}", v);
}
}
Run Code Online (Sandbox Code Playgroud)
相对于仅使用'static
生命周期,使用现有包含类型以及i32
将内部(迭代)类型使用的方式,此代码大大简化了,但是归纳起来仅显示了问题所在。
公认的答案解决了不使用特征'static
和+ 'a
与特征一起使用的问题的第一部分。我仍然对实际代码有疑问,这是一个LazyList
实现。我已经发布了该信息,因为我是错误地实现了IntoIterator来引用LazyList实现,还是这是Rust的错误?。
你已经正确地实施了以引用迭代器VecWrapper
,且s 现场为节目的整个长度 -的'static
寿命。
您可能希望拥有一个通用的寿命。然后将为每个实例提供唯一的具体生命期。通常,我们很懒,只是给这辈子起个名字'a
:
struct VecWrapper(Vec<i32>);
impl VecWrapper {
fn iter(&self) -> Iter {
Iter(Box::new(self.0.iter()))
}
}
struct Iter<'a>(Box<Iterator<Item = &'a i32> + 'a>);
impl<'a> Iterator for Iter<'a> {
type Item = &'a i32;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}
impl<'a> IntoIterator for &'a VecWrapper {
type Item = &'a i32;
type IntoIter = Iter<'a>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
fn main() {
let test = VecWrapper(vec![1, 2, 3]); // not working
for v in &test {
println!("{}", v);
}
}
Run Code Online (Sandbox Code Playgroud)
重要更改:
Box<Iterator<Item = &'a i32> + 'a>
- + 'a
已添加。这是必需的,因为特征对象将假定没有内部值引用任何寿命短的内容。Item
目前类型&'a i32
。<'a>
)。也可以看看:
通常,这里没有理由使用特征对象。我只是直接嵌入迭代器:
struct Iter<'a>(std::slice::Iter<'a, i32>);
Run Code Online (Sandbox Code Playgroud)
这就避免了需要任何间接的需求,在这种情况下,这种间接方式还是不可用的。另外,它更明显地将生命周期耦合在一起。
归档时间: |
|
查看次数: |
530 次 |
最近记录: |