【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分于上海。

相关推荐
星栈独行4 分钟前
Node 接口该写同步还是异步?
服务器·开发语言·后端·程序人生·node.js
小刘学技术16 分钟前
AI人工智能中的类别不平衡问题:成因、影响与解决方案
开发语言·人工智能·python·机器学习
兰令水22 分钟前
hot100【acm版】【2026.7.21打卡-java版本】
java·开发语言·算法·leetcode·面试
2501_9142459332 分钟前
Java应用性能调优与生产监控部署:2026年实战手册
java·开发语言
雨师@36 分钟前
python通过rust编写组件扩展自己的能力
python·rust
时光不染。回忆不淡1 小时前
Python基础语法教程
开发语言·python
爱喝水的鱼丶1 小时前
SAP-ABAP:一次关于“交货日期”的增强需求:从复杂增强到标准功能的回归之旅
运维·开发语言·性能优化·sap·abap·经验交流
星恒随风1 小时前
C++ STL 详解:list 的使用、迭代器失效、模拟实现与 vector 对比
开发语言·数据结构·c++·笔记·学习·list
Tim_101 小时前
【C++】019、内存泄漏
java·开发语言
牢姐与蒯2 小时前
c++之异常
开发语言·c++·c++11