Rust自定义迭代器
Rust自定义迭代器
Rust要自定迭代器要实现Iterator这个Trait,就可以使用next方法,也可以实现IntoIterator方法就可以把对象转换为一个迭代器。这与Python中的可迭代对象和迭代器的概念类似。在Python中,实现了__iter__方法就是一个可迭代对象,再实现__next__方法就是一个迭代器。
Python的迭代器和可迭代对象
Iterator定义
pub trait Iterator{
type Item;
fn next(&mut self) -> Option<Self::Item>;
}
实现了Iterator的对象就是一个迭代器类型
IntoIterator
实现了IntoIterator就可以使用for in循环了
pub trait IntoIterator {
type Item;
type IntoIter: Iterator<Item=Self::Item>;
fn into_iter(self) -> Self::IntoIter;
}
// 实现了Iterator可以自动实现IntoIterator
impl<I: Iterator> IntoIterator for I {
type Item = I::Item;
type IntoIter = I;
#[inline]
fn into_iter(self) -> I {
self
}
}
示例
// 节点
struct Node<T> {
value: T,
next: Option<Box<Node<T>>>
}
impl <T> Node<T> {
fn new(value: T, next: Option<Box<Node<T>>>) -> Self {
Node { value, next}
}
}
// 链表
struct LinkedList<T> {
length: usize,
head: Option<Box<Node<T>>>
}
impl<T> LinkedList<T> {
fn new() -> Self {
LinkedList { length: 0, head: None }
}
fn push_front(&mut self, value: T) {
let new_node = Box::new(Node::new(value, self.head.take()));
self.head = Some(new_node);
self.length += 1;
}
fn pop_front(&mut self) -> Option<T> {
self.head.take().map(|node| {
self.head = node.next;
self.length -= 1;
node.value
})
}
fn peek(&self) -> Option<&T> {
self.head.as_ref().map(|node| {
&node.value
})
}
fn len(&self) -> usize {
self.length
}
fn is_empty(&self) -> bool {
self.length == 0
}
fn contains(&self, value: &T) -> bool where T: PartialEq {
let mut current = self.head.as_deref();
while let Some(node) = current {
if &node.value == value {
return true;
}
current = node.next.as_deref();
}
return false;
}
fn reverse(&mut self) {
let mut pre: Option<Box<Node<T>>> = None;
let mut current = self.head.take();
while let Some(mut node) = current{
current = node.next;
node.next = pre;
pre = Some(node);
}
self.head = pre;
}
fn reverse_recursive(&mut self) {
fn recusive<T> (node: Option<Box<Node<T>>>, pre: Option<Box<Node<T>>>) -> Option<Box<Node<T>>> {
if node.is_none() {
return pre;
}
let mut cur = node.unwrap();
let nxt = cur.next.take();
cur.next = pre;
return recusive(nxt, Some(cur));
}
self.head = recusive(self.head.take(), None);
}
fn reverse_recursive2(&mut self) {
fn recusive<T>(node: Option<Box<Node<T>>>, pre: Option<Box<Node<T>>>) -> Option<Box<Node<T>>>{
match node {
Some(mut cur) => {
let next = cur.next.take();
cur.next = pre;
recusive(next, Some(cur))
},
None => pre
}
}
self.head = recusive(self.head.take(), None);
}
fn clear(&mut self) {
self.length = 0;
self.head = None;
}
}
// 获取所有权的迭代器
struct IntoIter<T> {
list: LinkedList<T>
}
// 不可变引用迭代器
struct Iter<'a, T>{
next: Option<&'a Node<T>>
}
// 可变引用迭代器
struct IterMut<'a, T> {
next: Option<&'a mut Node<T>>
}
// 1. 首先给上面三个迭代器实现Iterator, 成为真正的迭代器类型
impl<T> Iterator for IntoIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.list.pop_front()
}
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
self.next.map(|node| {
self.next = node.next.as_deref();
&node.value
})
}
}
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
self.next.take().map(|node| {
self.next = node.next.as_deref_mut();
&mut node.value
})
}
}
// 然后给LinkedList实现IntoIterator,让LinkedList可以转换为迭代器,可以使用for in
impl<T> IntoIterator for LinkedList<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
IntoIter{
list: self
}
}
}
// 然后给LinkedList实现iter,iter_mut 返回不可变引用、可变引用迭代器
impl<T> LinkedList<T> {
fn iter(&self) -> Iter<'_, T> {
Iter { next: self.head.as_deref() }
}
fn iter_mut(&mut self) -> IterMut<'_, T> {
IterMut{
next: self.head.as_deref_mut()
}
}
}
fn main() {
let mut list = LinkedList::new();
list.push_front(1);
list.push_front(2);
list.push_front(3);
list.push_front(4);
list.reverse();
for node in list.iter() {
println!("after reverse: {node}");
}
list.pop_front();
for node in list.iter() {
println!("after pop: {node}");
}
for node in list.iter_mut() {
*node = *node * 2;
}
list.reverse();
for node in list {
println!("dobule : {node}");
}
}

浙公网安备 33010602011771号