我尝试为树实现IntoIterator,然后我可以使用“for in Tree ",否则我必须在TreeIter{.}中为它编写,但是生存期错误:
use std::iter::IntoIterator;
#[derive(Debug)]
struct Tree<T> {
data: T,
}
struct TreeIter<'a, T> {
tree: &'a Tree<T>,
count: i32,
}
impl<'a, T> IntoIterator for Tree<T> {
type Item = &'a Tree<T>;
type IntoIter = TreeIter<'a, T>;
fn into_iter(&'a self) -> Self::IntoIter {
TreeIter { tree: &self, count: 0 }
}
}
impl<'a, T> Iterator for TreeIter<'a, T>
{
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
self.count += 1;
if self.count > 5 {
return None;
} else {
return Some(&self.tree.data);
}
}
}
fn main() {
let tree = Tree { data: "abc" };
for v in tree {
println!("{:?}", v);
}
/*
let treeiter = TreeIter{tree: &tree, count: 0};
for (i, &v) in treeiter.enumerate() {
println!("{}: {}", i, v);
}
*/
}got错误: errorE0207:生命周期参数'a不受impl特性的约束
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
--> test-iter/src/main.rs:13:6
|
13 | impl<'a, T> IntoIterator for Tree<T> {
| ^^ unconstrained lifetime parameter发布于 2021-01-08 07:18:45
考虑到您的TreeIter结构和其他一切,您不希望在迭代中使用Tree,您只希望它引用元素。所以你想
impl<'a, T> IntoIterator for &'a Tree<T> {
// ^^^^^^^^^^^ implement for references to Trees
type Item = &'a T;
// ^^^^^ this needs to match Iterator::Item for TreeIter
type IntoIter = TreeIter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
// ^^^^ self is a &'a Tree<T>
TreeIter { tree: self, count: 0 }
}
}然后,您可以在如下的for循环中使用它:
let tree = Tree { data: "abc" };
for v in &tree {
// ^ only iterate via reference
println!("{:?}", v);
}发布于 2021-01-08 07:36:09
into_iter()的意思是批发获得收藏的所有权。集合被移动到迭代器中,并被迭代所消耗,而不是通过引用借用,而只是查看。该行为由iter()和iter_mut()提供。因此,您的代码在概念上是有缺陷的,编译器错误反映了这一点:into_iter不使用已具有任何生存期的集合;它需要一个集合,并立即结束它的生命周期。没有'a让你impl<'a>结束。用正确的思想去实现它,它是有效的。
struct IntoIter<T> { // e.g. same convention as std::vec::IntoIter
tree: Tree<T>,
pos: i32,
}
// due to your dummy implementation, we need T: Copy, but a real implementation shouldn't need it
impl<T: Copy> IntoIterator for Tree<T> {
type Item = T; // why would iterating over a tree give you trees?
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
IntoIter { tree: self, pos: 0 }
}
}
impl<T: Copy> Iterator for IntoIter<T> {
type Item = T; // iterating over an IntoIter should give values moved out of the container (in this case we're copying the same value a few times and pretending they were moved)
fn next(&mut self) -> Option<Self::Item> {
if self.pos < 5 {
self.pos += 1;
Some(self.tree.data)
} else {
None
}
}
}
fn main() {
for i in (Tree { data: 1 }) { println!("{}", i) }
}请注意,为借入集合提供IntoIterator也是传统的做法。再一次,into_iter()应该被看作是在消耗它的论点.但是“消费”一笔借款实际上并不消耗它所指的东西。这将使用您的迭代器类型,但请注意,这个特性实现不是我们在上面的main中使用的。
struct Iter<'a, T> {
tree: &'a Tree<T>,
pos: i32
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> { todo!() }
}
impl<'a, T> IntoIterator for &'a Tree<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> { todo!() }
}
struct IterMut<'a, T> {
tree: &'a mut Tree<T>,
pos: i32
}
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> { todo!() }
}
impl<'a, T> IntoIterator for &'a mut Tree<T> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
fn into_iter(self) -> IterMut<'a, T> { todo!() }
}如果你这么做了,这些都会被调用
fn main() {
let mut tree = Tree { data: 1 };
for i in &tree { println!("{}", i) } // IntoIter for borrow
for i in &mut tree { println!("{}", i) } // IntoIter for mutable borrow
}https://stackoverflow.com/questions/65624661
复制相似问题