【Rust】08-集合类型、字符串与迭代器入门

集合类型、字符串与迭代器入门

学习目标

  • 掌握 Vec<T>HashMap<K, V> 的基本用法。
  • 理解 String&str 的区别。
  • 使用迭代器进行常见数据处理。

Vec

Vec<T> 是可增长数组,所有元素类型相同:

rust 复制代码
fn main() {
    let mut numbers = Vec::new();
    numbers.push(10);
    numbers.push(20);
    numbers.push(30);

    println!("{numbers:?}");
}

也可以用宏创建:

rust 复制代码
let numbers = vec![10, 20, 30];

读取元素有两种常见方式:

rust 复制代码
let numbers = vec![10, 20, 30];

let first = numbers[0];
let maybe_first = numbers.get(0);

println!("{first}");
println!("{maybe_first:?}");

索引越界会 panic,get 返回 Option<&T>,更适合处理不确定位置。

遍历 Vec

rust 复制代码
fn main() {
    let numbers = vec![10, 20, 30];

    for number in &numbers {
        println!("{number}");
    }
}

如果需要修改元素:

rust 复制代码
fn main() {
    let mut numbers = vec![10, 20, 30];

    for number in &mut numbers {
        *number += 1;
    }

    println!("{numbers:?}");
}

*number 是解引用,用于修改引用指向的值。

HashMap

HashMap<K, V> 存储键值对:

rust 复制代码
use std::collections::HashMap;

fn main() {
    let mut scores = HashMap::new();
    scores.insert(String::from("Alice"), 90);
    scores.insert(String::from("Bob"), 85);

    println!("{scores:?}");
}

读取值:

rust 复制代码
let name = String::from("Alice");
let score = scores.get(&name);

get 返回 Option<&V>,因为键可能不存在。

entry API

entry 常用于"如果不存在就插入":

rust 复制代码
use std::collections::HashMap;

fn main() {
    let mut counts = HashMap::new();

    for word in ["rust", "go", "rust"] {
        let count = counts.entry(word).or_insert(0);
        *count += 1;
    }

    println!("{counts:?}");
}

这是统计词频、累加分组数据时非常常用的写法。

String 与 &str

String 是可增长、拥有所有权的 UTF-8 字符串。&str 是字符串切片,通常是借用视图。

rust 复制代码
fn print_text(text: &str) {
    println!("{text}");
}

fn main() {
    let owned = String::from("hello");
    let literal = "world";

    print_text(&owned);
    print_text(literal);
}

函数参数优先写 &str,可以同时接收 String 和字符串字面量。

追加字符串:

rust 复制代码
let mut text = String::from("hello");
text.push(' ');
text.push_str("world");

字符串遍历

Rust 字符串是 UTF-8 编码,不支持按字符位置直接索引:

rust 复制代码
let text = String::from("你好");
// let ch = text[0]; // 编译错误

可以按字符遍历:

rust 复制代码
for ch in text.chars() {
    println!("{ch}");
}

也可以按字节遍历:

rust 复制代码
for byte in text.bytes() {
    println!("{byte}");
}

迭代器

迭代器让集合处理更简洁:

rust 复制代码
fn main() {
    let numbers = vec![1, 2, 3, 4, 5];

    let doubled: Vec<i32> = numbers
        .iter()
        .map(|n| n * 2)
        .collect();

    println!("{doubled:?}");
}

过滤:

rust 复制代码
let even: Vec<i32> = numbers
    .iter()
    .copied()
    .filter(|n| n % 2 == 0)
    .collect();

求和:

rust 复制代码
let total: i32 = numbers.iter().sum();

iter、iter_mut、into_iter

  • iter():按不可变引用遍历。
  • iter_mut():按可变引用遍历。
  • into_iter():消费集合,按值遍历。
rust 复制代码
let names = vec![String::from("Alice"), String::from("Bob")];

for name in names.into_iter() {
    println!("{name}");
}

// names 此后不可用

常见误区

  • Vec<T> 是动态数组,不等于链表。
  • HashMap::get 返回 Option,因为键可能不存在。
  • Rust 字符串不能随意按数字下标取字符。
  • 迭代器通常是惰性的,很多操作需要 collectsum 等消费方法才会执行。

练习

  1. Vec<i32> 存储 5 个数字,计算总和。
  2. HashMap<&str, i32> 统计数组中单词出现次数。
  3. 把一个数字列表过滤成偶数列表,再把每个偶数乘以 10。

后记

2026年6月10日17点31分于上海。

相关推荐
花褪残红青杏小7 小时前
Rust图像处理第8节-暗角 & 复古胶片特效:四周衰减中心高亮
rust·webassembly·图形学
独孤留白1 天前
从C到Rust:Rust 的 Trait 不是Interface,那是什么?
rust
花褪残红青杏小1 天前
Rust图像处理第7节-马赛克像素化:分块取平均色实现打码风格
rust·webassembly·图形学
hez20101 天前
在 .NET 上构建超大托管数组
c#·.net·.net core·gc·clr
doiito2 天前
【Agent Harness】Gliding Horse 设计细节 -- 不跟风开发自己的AI Agent
架构·rust·agent
doiito2 天前
【Agent Harness】Gliding Horse 核心设计理念,不跟风开发自己的AI Agent
ai·rust·架构设计·系统设计·ai agent
花褪残红青杏小2 天前
Rust图像处理第6节- 均值模糊 & 中值模糊:3×3 邻域的两种经典玩法
rust·webassembly·图形学
子兮曰3 天前
前端工具链的「Rust 化」:一场没有赢家的军备竞赛?
前端·后端·rust
星栈3 天前
写 Dioxus Demo 不难,难的是把它写成项目
前端·rust·前端框架
mCell3 天前
【锐评】桌面端技术营销:别拿跑分当工程判断
前端·rust·electron