Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Collections: Vec, HashMap, and Iterators
集合:VecHashMap 与迭代器

What you’ll learn: How the most common Rust collections compare to Java’s List, Map, and stream-based traversal patterns.
本章将学习: Rust 最常用的集合类型,分别如何对应 Java 的 ListMap 和基于 Stream 的遍历模式。

Difficulty: 🟢 Beginner
难度: 🟢 初级

Vec<T> vs List<T>
Vec<T>List<T>

Vec<T> is the workhorse collection in Rust.
Vec<T> 是 Rust 里最常干活的集合类型。

#![allow(unused)]
fn main() {
let mut numbers = vec![1, 2, 3];
numbers.push(4);
}

If Java developers are tempted to ask “what is the interface type here?”, the answer is usually “there isn’t one yet, because the concrete vector is enough.”
如果脑子里冒出来“这里的接口类型是什么”,Rust 的常见答案往往是:“暂时没有,因为具体的 Vec 已经够用了。”

HashMap<K, V> vs Map<K, V>
HashMap<K, V>Map<K, V>

#![allow(unused)]
fn main() {
use std::collections::HashMap;

let mut scores = HashMap::new();
scores.insert("ada", 98);
scores.insert("grace", 100);
}

Lookups return Option<&V> rather than null.
查找结果返回的是 Option<&V>,不是 null

Iteration
迭代

#![allow(unused)]
fn main() {
for value in &numbers {
    println!("{value}");
}
}

Rust makes ownership visible during iteration:
Rust 会在迭代时把所有权意图直接摆出来:

  • iter() borrows items
    iter() 借用元素。
  • iter_mut() mutably borrows items
    iter_mut() 可变借用元素。
  • into_iter() consumes the collection
    into_iter() 消耗整个集合。

That third case is where many Java developers first feel the ownership model in collection code.
第三种情况往往是很多 Java 开发者第一次在集合代码里真正感受到所有权模型的地方。

Iterators vs Streams
迭代器与 Stream

Java StreamRust iterator
lazy pipeline
惰性流水线
lazy pipeline
惰性流水线
terminal operation required
需要终止操作
terminal operation required
需要终止操作
often object-heavy
常常对象味更重
often zero-cost and monomorphized
通常零成本、单态化
#![allow(unused)]
fn main() {
let doubled: Vec<_> = numbers
    .iter()
    .map(|n| n * 2)
    .collect();
}

Advice
建议

  • start with Vec before searching for more abstract collection models
    先把 Vec 用明白,再考虑更抽象的集合模型。
  • use Option-aware lookups rather than assuming missing values are exceptional
    查找缺失值时顺着 Option 去处理,不要先把它想成异常。
  • choose iter, iter_mut, or into_iter based on ownership intent
    根据所有权意图去选 iteriter_mut 还是 into_iter

Once these three collection patterns click, a large amount of day-to-day Rust code becomes readable.
只要这三类集合模式顺下来,大量日常 Rust 代码就开始变得好读了。