迭代器 iter
不同的语言中都有迭代器这个概念,Rust也不例外,例如常见的数组:
let mut test_vec = vec![1,2,3,4,5,6]; let it_vec = test_vec.iter(); for val in it_vec { println!("Got: {}", val); }
可以看到,这里拿到的test_vec
本质上只是一个迭代器,迭代器的接口通常如下:
pub trait Iterator { type Item; fn next(&mut self) -> Option<Self::Item>; // 此处省略了方法的默认实现 }
这里的type
是Rust中的一种叫做关联类型(associated type)的特性,一般出现在trait
中,表示当前的trait
在使用的时候,需要对类型进行指定。其本质类似于泛型,例如我们也可以以如下的方式实现这个接口
impl Iterator for Counter { type Item = u32; fn next(&mut self) -> Option<Self::Item> { // --snip--
这里我们给Counter对象实现了一个Iterator
接口,并且指明了在这里的Item
表示u32
,则在之后对Counter的迭代对象进行迭代的时候,其一定会返回Option<u32>
。在迭代器中,有几种不同的迭代器:
iter
:正如声明,这种返回的是一个不可变的迭代器,不能修改迭代器中的元素,但是也因此不会发生迭代器中对象的所有权转移,也就不会发生对象的销毁,被迭代对象就依然可被使用iter_mut
:与前者的区别在于,返回的是可变的迭代器对象into_iter
:这种迭代器进行迭代的时候,迭代器的对象会被消费,也就是发生了所有权的转移,此时被迭代器对象不可在被使用
特征 | iter | iter_mut | into_iter |
---|---|---|---|
迭代元素对象是否可变 | 不可变 | 可变 | 不可变 |
所有权是否变化 | 未变 | 未变 | 变化为迭代对象 |
以下代码就能说明这三者的区别:
let mut test = vec![1,2,3,4]; // let mut iter = test.iter(); println!("iter mutable"); for it in test.iter_mut() { println!("target is {}", it); *it = 1; } println!("iter"); for it in test.iter() { println!("target is {}", it); } println!("iter into"); for it in test.into_iter() { println!("target is {}", it); } // 在这之后test对象就被销毁了 // println!("{:?}",test); 这里将会报错