










下面我将以零基础教学的视角,逐一讲述 Rust 标准库 std 中最常用、最核心的模块和类型。每一节我会说明:它是什么、为什么需要、怎么用、有哪些关键方法和常见例子,并尽量结合之前冒险者程序中的代码。
在 Rust 里,每个程序都会自动导入一些最基本的东西,不需要你写 use std::...。它们包括:
Option::Some、Option::NoneResult::Ok、Result::ErrVec、String、Boxprintln!、format! 宏Clone、Copy、Drop 等基础 trait理解方式: 就像一盒你买来就能直接用的基础文具(铅笔、橡皮、尺子),不需要再专门申请。因此初学者最先接触的 Option、Result、Vec 等,都是预导入的,可以直接使用。
Option 是一个枚举,代表一个值可能存在,也可能不存在。
enum Option<T> {
Some(T), // 有值
None, // 没有值
}
为什么需要? 在很多语言里,null 或 None 常常导致崩溃。Rust 用 Option 强制你处理“没有值”的情况,从而避免空指针异常。
常用方法:
unwrap():如果有值就拿出来,没有值就崩溃(不要随意使用)。expect("信息"):类似 unwrap,但可以自定义错误信息。is_some() / is_none():判断是否有值。match 或 if let:安全地取出值。教学代码例子:
let secret = Some("宝藏"); // secret 是 Option<&str>,里面有 "宝藏"
match secret {
Some(msg) => println!("{}", msg),
None => println!("啥也没有"),
}
Result 也是枚举,专用于可能出错的操作。
enum Result<T, E> {
Ok(T), // 成功,带着结果 T
Err(E), // 失败,带着错误信息 E
}
为什么需要? 打开文件、网络连接、读取输入等都可能失败。Result 让你必须处理错误,否则编译不通过。
常用方法:
unwrap() / expect():成功拿值,失败则崩溃。? 运算符:如果成功就继续,失败就立刻把错误返回给上级函数。is_ok() / is_err():判断是否成功。教学代码例子:
fn use_item(&mut self, index: usize) -> Result<Item, GameError> {
if index >= self.inventory.len() {
return Err(GameError::NoItem); // 返回错误
}
Ok(self.inventory.remove(index)) // 返回成功
}
// 调用处用 match 处理
match hero.use_item(0) {
Ok(item) => log!("使用物品: {}", item),
Err(e) => log!("错误: {}", e),
}
&str(字符串切片):对一段 UTF-8 文本的“借用引用”,不能修改,通常是 "hello" 这种字面量。String:拥有所有权的、可增长的字符串,可以修改和添加内容。关键区别: &str 便宜、轻量,但无权修改;String 是独立的,可以随意增删改。
常用转换和方法:
"hello".to_string() 或 String::from("hello"):字面量变 String。push_str(" world"):追加切片。push('!'):追加单个字符。len():获取字节长度(UTF-8 下要注意中文多字节)。as_str():得到 &str。教学代码中:
let name: &str = "千字文"; // 切片,借用
let s = "卷轴".to_string(); // String,拥有所有权
book_bag.add(s); // s 被移动进背包
Vec<T> 是存放很多相同类型元素的列表,可自动增长。
创建和操作:
Vec::new():空向量。vec![1,2,3]:宏快速创建。.push(元素):在末尾加入。.pop():移除末尾并返回 Option。.len():获取元素个数。.get(index):安全索引,返回 Option<&T>。v[0] 索引会崩溃,推荐用 get。教学代码中:
let mut inventory: Vec<Item> = Vec::new();
inventory.push(Item::Sword(30));
// 迭代
for item in &inventory { ... }
std::fmt 模块提供了如何把各种类型变成字符串打印出来的 trait:
Debug:用于调试,用 {:?} 打印,几乎所有标准类型都实现了,也可用 #[derive(Debug)] 自动生成。Display:用于用户友好的展示,用 {} 打印,需要手动实现。教学代码中我们实现了 Display:
impl fmt::Display for Item {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Item::Sword(atk) => write!(f, "剑(攻{})", atk),
...
}
}
}
这样 println!("{}", item) 就会输出友好的文字。
Copy:轻量拷贝,比如整数、布尔,赋值时自动复制,原变量仍可使用。无法手动实现 Copy 的类型不能添加。Clone:显式复制,调用 .clone(),适用于字符串、Vec 等复杂类型,会有性能开销。教学意义: 初学者常困惑于所有权转移,Copy 类型不需要担心;非 Copy 类型要用 clone() 来深复制,如 s1.clone()。
std::collections::HashMap<K, V> 通过键快速查找值。
常用方法:
HashMap::new() 创建。.insert(key, value) 插入。.get(&key) 返回 Option<&V>。.entry(key).or_insert(value) 如果有键就返回其值,没有就插入并提供可变引用。代码例子(未在教学代码中,但典型):
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert("Blue", 10);
let team_score = scores.get("Blue").unwrap_or(&0);
这些都是帮助管理内存和所有权的高级工具,但在零基础教学中先建立印象即可。
Box<T>:把数据放在堆上,比如解决递归类型的尺寸问题。简单理解:一个指向堆内存的指针,拥有数据。Rc<T>:单线程引用计数,允许多个所有者共享数据,不可变引用。用 Rc::clone(&rc) 增加引用。RefCell<T>:内部可变性,允许在只拥有不可变引用时修改内部值,但规则由编译时检查移到运行时,违规会 panic。Arc<T>:线程安全的 Rc,用于多线程共享。Mutex<T>:互斥锁,配合 Arc 可以安全地在多线程中修改同一份数据。教学代码中:
// Rc + RefCell 让多个指针共享一个可变冒险者
let adv = Rc::new(RefCell::new(Adventurer::new("共享者")));
let adv2 = Rc::clone(&adv);
adv2.borrow_mut().health -= 10; // 修改内部
std::io 提供了 Read 和 Write trait,以及标准输入 stdin()、标准输出 stdout()。
最常用的是防止窗口闪退:
let mut input = String::new();
std::io::stdin().read_line(&mut input).unwrap(); // 等待用户输入回车
另外也包含 File 的读取,但 File 属于 std::fs,io 提供 Read trait。
std::fs 处理文件和目录。
常用:
File::open("路径"):打开文件,返回 Result<File>。read_to_string("路径"):一次性读取为字符串。write("路径", 内容):写入文件。create_dir("目录") 等。教学代码中:
let mut file = File::open("adventure.toml")?;
let mut content = String::new();
file.read_to_string(&mut content)?;
std::thread::spawn(闭包):创建新线程。move 闭包:强制移动所有权进线程。handle.join().unwrap():等待线程结束。Arc<Mutex<T>>:多线程共享可变数据。教学代码:
let team = Arc::new(Mutex::new(vec![]));
let team2 = Arc::clone(&team);
thread::spawn(move || {
team2.lock().unwrap().push("战友A".to_string());
}).join().unwrap();
迭代器是对数据序列进行操作的强大工具,来自 std::iter。
核心方法:
.iter() / .iter_mut() / .into_iter() 获取迭代器。.map(|x| ...) 转换每个元素。.filter(|x| ...) 保留符合条件的元素。.collect() 把迭代器变回集合。.sum(), .count(), .find() 等消费者方法。教学代码:
let strong: Vec<_> = items.iter()
.filter(|it| matches!(it, Item::Sword(a) if *a > 5))
.collect();
std::error::Error 是所有错误类型的公共 trait,通常配合 Box<dyn Error> 使用,表示任意类型的错误。自定义错误只要实现了 Display 和 Debug,再 impl Error for MyError {} 即可。
教学代码:
fn load_config(path: &str) -> Result<String, Box<dyn Error>> { ... }
std::env:获取环境变量、命令行参数 args()。std::process:运行外部命令,退出程序 exit()。std::time:Duration(时长)、Instant(时间点)。std::cmp:Ordering 枚举(Less, Equal, Greater),max/min 函数。std::char:判断字符类型的方法。std::mem:内存操作,如 swap, size_of。对于零基础学习者,建议按照以下顺序逐步掌握:
Option、Result、String/&str、Vec(最常用)fmt::Display/Debug、Clone/Copy(打印与复制)HashMap(当需要字典时)Box、Rc、RefCell(理解所有权进阶)thread、Arc、Mutex(并发入门)fs、io(文件操作)map/filter/collect 等)每学一个,都可以在冒险者程序里找到对应示例,通过阅读注释 + 运行程序 + 动手修改的方式,逐步把 Rust 的标准库用起来。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。