美文网首页
【RUST_BASIC】Vector 与迭代器

【RUST_BASIC】Vector 与迭代器

作者: ixiaolong | 来源:发表于2021-11-21 19:27 被阅读0次

1 Vector

https://doc.rust-lang.org/std/vec/struct.Vec.html

2 迭代器简介

迭代器(iterator)负责遍历序列中的每一项和决定序列何时结束的逻辑。在 Rust 中,迭代器是惰性的(lazy),这意味着在调用方法使用迭代器之前它都不会有效果:

let v1 = vec![1, 2, 3];
let v1_iter = v1.iter();

上述这段代码本身并没有任何用处。

使用 for 循环使用迭代器:

let v1 = vec![1, 2, 3];
let v1_iter = v1.iter();
for val in v1_iter {
    println!("Got: {}", val);
}

迭代器都实现了一个叫做 Iterator 的定义于标准库的 trait:

pub trait Iterator {
    type Item;
    fn next(&mut self) -> Option<Self::Item>;
    // 此处省略了方法的默认实现
}

这段代码表明实现 Iterator trait 要求同时定义一个 Item 类型,这个 Item 类型将是迭代器返回元素的类型;next 是 Iterator 实现者被要求定义的唯一方法,一次返回迭代器中的一个项,封装在 Some 中,当迭代器结束时,它返回 None

#[test]
fn iterator_demonstration() {
    let v1 = vec![1, 2, 3];
    let mut v1_iter = v1.iter();
    assert_eq!(v1_iter.next(), Some(&1));
    assert_eq!(v1_iter.next(), Some(&2));
    assert_eq!(v1_iter.next(), Some(&3));
    assert_eq!(v1_iter.next(), None);
}

注意 v1_iter 需要是可变的,因为在迭代器上调用 next 方法改变了迭代器中用来记录序列位置的状态。使用 for 循环时无需使 v1_iter 可变因为 for 循环会获取 v1_iter 的所有权并在后台使 v1_iter 可变。
另外需要注意到从 next 调用中得到的值是 vector 的不可变引用。iter 方法生成一个不可变引用的迭代器,如果需要一个获取 v1 所有权并返回拥有所有权的迭代器,则可以调用 into_iter;如果希望迭代可变引用,可以调用 iter_mut

3 消费迭代器

Iterator trait 有一系列不同的由标准库提供默认实现的方法,其中一些方法调用了 next 方法,这些方法被称为消费适配器(consuming adaptors),因为调用他们会消耗迭代器。

#[test]
fn iterator_sum() {
    let v1 = vec![1, 2, 3];
    let v1_iter = v1.iter();
    let total: i32 = v1_iter.sum();
    assert_eq!(total, 6);
}

4 迭代器适配器

Iterator trait 中定义了另一类方法,允许将当前迭代器变为不同类型的迭代器,例如下面的 map 方法使用闭包来调用每个元素以生成新的迭代器,调用 collect 方法消费新迭代器并创建一个 Vector:

let v1: Vec<i32> = vec![1, 2, 3];
let v2: Vec<_> = v1.iter().map(|x| x + 1).collect();

5 性能

通过将阿瑟·柯南·道尔的“福尔摩斯探案集”的全部内容加载进 String 并寻找其中的单词 “the”,如下是 for 循环版本和迭代器版本的 search 函数的性能测试结果:

test bench_search_for  ... bench:  19,620,300 ns/iter (+/- 915,700)
test bench_search_iter ... bench:  19,234,900 ns/iter (+/- 657,200)

迭代器作为一个高级的抽象,被编译成了与手写的底层代码大体一致性能代码。迭代器是 Rust 的零成本抽象(zero-cost abstractions)之一,它意味着抽象并不会引入运行时开销。

参考

https://kaisery.github.io/trpl-zh-cn/ch13-02-iterators.html

相关文章

  • 【RUST_BASIC】Vector 与迭代器

    1 Vector https://doc.rust-lang.org/std/vec/struct.Vec.htm...

  • 16-迭代器与ConcurrentModificationExc

    迭代器与ConcurrentModificationException Vector、ArrayList在迭代的时...

  • 13.C++ vector 操作

    vector初始化 vector大小 数组方式操作vector 迭代器方式操作vector 反向迭代器操作vect...

  • vector使用

    初始化 添加元素 vector的其他操作 vector ::size_type 遍历 迭代器 迭代器运算

  • C++boolan part3_week4

    1. 迭代器 1.1 迭代器的种类 使用随机访问迭代器的容器:array, vector,deque使用双向迭代器...

  • STL迭代器失效

    迭代器在移除元素时迭代器可能失效。vector如果开辟新的内存时迭代器可能失效。新增元素时尾迭代器可能失效。......

  • 线程安全list的遍历

    Vector Vector在迭代器遍历时,其他线程增删元素,会抛ConcurrentModificationExc...

  • 迭代器实战——数组分块工具

    迭代器简介 c++中经常会用到这样的写法: 上面代码中,it即是迭代器,通过迭代器自增可以遍历vector容器,而...

  • C++ __STL学习过程

    1.vector 作为容量 初始化: vector作为函数参数进行调用 2.iterator 迭代器 const...

  • C++ 常用代码

    vector 迭代器遍历 C++ 函数模板 冒泡排序 快速排序

网友评论

      本文标题:【RUST_BASIC】Vector 与迭代器

      本文链接:https://www.haomeiwen.com/subject/aqjmtrtx.html