关于 rust-stdlib
面向 Rust 开发者的标准库 API 选型与组合技能,涵盖集合、指针、字符串、I/O、迭代器和并发原语等场景。
主要功能
- 01选择集合与智能指针
- 02选用字符串和路径类型
- 03组合 Option 与 Result 链
- 04选择 I/O trait 和迭代器模式
- 05使用标准库并发原语
适用场景
- 01为查找或排序选择集合
- 02选择所有权与内部可变性类型
- 03构建文件 I/O 和迭代器流程
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ full-stack-skills/ rust-skills --skill rust-stdlib安装后在 Claude Code 中输入/rust-stdlib确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlexamples/golden-stdlib/Cargo.lockCargo.tomlexamples/golden-stdlib/src/lib.rsreferences/collections.mdinterior-mutability.mdio-streams.mditerators.mdoption-result-combinators.mdprocess-and-fs.mdsmart-pointers.mdstd-concurrency.mdstd-module-index.mdstring-types.md详细介绍
Rust 标准库 — API 选择与组合
权威来源:Rust 标准库 — 规范参考。完整模块图请阅读
references/std-module-index.md。
本技能负责选择和组合 std API:选择哪种集合、哪种智能指针、哪种字符串类型、哪种 I/O trait、哪种迭代器模式。本技能不负责语言语义(rust-stable)、异步运行时(rust-concurrency)或应用层问题(领域技能)。
能力边界
✅ 擅长
- 选择合适的集合(HashMap、BTreeMap、Vec、VecDeque、LinkedList、BinaryHeap)
- 选择合适的智能指针(Box、Rc、Arc、RefCell、Mutex、OnceLock)
- 选择合适的字符串类型(String、&str、OsString、PathBuf、Cow)
- 选择内部可变性原语(Cell、RefCell、OnceCell、OnceLock、LazyLock)
- 设计 Option/Result 组合器链(map、and_then、unwrap_or_else、ok_or、transpose)
- 选择 I/O trait(Read、Write、BufRead、Seek、AsyncRead)
- 选择迭代器模式(iter、into_iter、所有权迭代器、惰性计算或收集)
- 使用 std 并发原语(thread、mpsc、barrier、Once、作用域线程)
- 选择时间 API(Duration、Instant、SystemTime、TryFromFloat)
- 跨平台路径处理(Path、PathBuf、fs、env、process::Command)
⚠️ 前置要求
- Rust 所有权和生命周期 — 参见
rust-stable - Cargo 和项目结构 — 参见
rust-cargo-build、rust-workspace
❌ 不在范围内
- 异步运行时(Tokio、async-std)→
rust-concurrency - 语言语义(所有权、trait、生命周期)→
rust-stable - 应用层问题(CLI、Web、数据库)→ 领域技能
- Unsafe 和 FFI →
rust-unsafe-ffi
数据隐私
本技能不会收集、存储或传输用户数据。
第 1 部分:集合
决策树
Need a collection?
│
├─ Key-value lookup?
│ ├─ Order doesn't matter, fast lookup → HashMap<K, V>
│ ├─ Need sorted iteration / range queries → BTreeMap<K, V>
│ └─ Tiny (<20 entries), linear scan OK → Vec<(K, V)> with .iter().find()
│
├─ Sequence?
│ ├─ Append/pop from end → Vec<T>
│ ├─ Push/pop from both ends → VecDeque<T>
│ ├─ Insert/remove from middle frequently → LinkedList<T> (rare; usually Vec is better)
│ └─ Priority queue / always-min-first → BinaryHeap<T>
│
├─ Set?
│ ├─ Fast membership, no order → HashSet<T>
│ └─ Sorted iteration → BTreeSet<T>
│
└─ No collection needed — use Vec<T>
速查表
| 类型 | 顺序 | 查找 | 插入 | 适用场景 |
|---|---|---|---|---|
Vec<T> | 插入顺序 | 按值 O(n),按索引 O(1) | push 均摊 O(1) | 默认序列 |
VecDeque<T> | 插入顺序 | 首尾 O(1) | 首尾 O(1) | 队列、滑动窗口 |
LinkedList<T> | 插入顺序 | O(n) | 使用游标可在任意位置 O(1) | 几乎从不使用;优先选择 Vec |
BinaryHeap<T> | 优先级 | peek O(1) | push/pop O(log n) | 优先队列 |
HashMap<K,V> | 无 | 平均 O(1) | 平均 O(1) | 快速查找,无顺序 |
BTreeMap<K,V> | 有序 | O(log n) | O(log n) | 有序键、范围查询 |
HashSet<T> | 无 | 平均 O(1) | 平均 O(1) | 成员检查 |
BTreeSet<T> | 有序 | O(log n) | O(log n) | 有序成员检查 |
有关分配行为、哈希器选择(BuildHasherDefault/FxHashMap)和 entry API 模式,请参阅 references/collections.md。
Entry API — 避免重复查找
use std::collections::HashMap;
let mut counts: HashMap<&str, u32> = HashMap::new();
for word in text.split_whitespace() {
*counts.entry(word).or_insert(0) += 1; // single hash, no double lookup
}
第 2 部分:智能指针
决策树
Need shared/indirected ownership?
│
├─ Single owner, heap-allocated → Box<T>
│
├─ Multiple readers, single thread → Rc<T>
│ └─ Need to mutate through shared ref → Rc<RefCell<T>>
│
├─ Multiple readers, multiple threads → Arc<T>
│ └─ Need to mutate through shared ref → Arc<Mutex<T>> or Arc<RwLock<T>>
│
├─ Need lazy one-time init → OnceLock<T> (sync) or once_cell::Lazy
│
└─ Need interior mutability (no shared ownership)?
├─ Copy type, simple → Cell<T>
├─ Non-Copy, complex → RefCell<T> (single thread)
└─ Multi-thread → Mutex<T> or RwLock<T>
速查表
| 类型 | 所有权 | 线程安全 | 可变性 | 用途 |
|---|---|---|---|---|
Box<T> | 单一 | 是 | 直接(拥有所有权) | 堆分配、递归类型 |
Rc<T> | 共享 | 否 | 仅不可变 | 引用计数,单线程 |
Arc<T> | 共享 | 是 | 仅不可变 | 原子引用计数,多线程 |
Cell<T> | 单一 | 否 | 内部可变(仅 Copy) | 简单可变状态 |
RefCell<T> | 单一 | 否 | 内部可变(运行时借用检查) | 通过共享引用进行修改 |
Mutex<T> | 单一 | 是 | 内部可变(锁) | 共享可变状态,同步 |
RwLock<T> | 单一 | 是 | 内部可变(读写锁) | 多读者、少写者 |
OnceLock<T> | 单一 | 是 | 一次性初始化 | 延迟初始化的全局变量,std::sync::OnceLock |
LazyLock<T> | 单一 | 是 | 一次性初始化,透明解引用 | 类似常量的全局变量(Rust 1.80+) |
有关权衡、drop 顺序,以及用于处理循环引用的 Weak<T>,请参阅 references/smart-pointers.md。
第 3 部分:字符串类型
决策树
Working with text?
│
├─ Function parameter → &str (always)
├─ Owned, mutable, UTF-8 → String
├─ Borrowed, UTF-8, with mixed owned/borrowed → Cow<'a, str>
├─ OS path (Windows/Unix native) → OsString (owned) / OsStr (borrowed)
├─ Filesystem path → PathBuf (owned) / Path (borrowed)
└─ Bytes that might not be UTF-8 → Vec<u8> / &[u8]
快速参考
| 类型 | 编码 | 是否拥有所有权? | 用途 |
|---|---|---|---|
&str | UTF-8 | 否 | 函数参数、字符串字面量 |
String | UTF-8 | 是 | 拥有所有权的可变 UTF-8 文本 |
OsString/OsStr | 平台原生 | 是/否 | 环境、进程参数 |
PathBuf/Path | 平台原生 | 是/否 | 文件系统路径 |
Cow<'a, str> | UTF-8 | 视情况而定 | 尽可能零拷贝,需要时拥有所有权 |
Vec<u8>/&[u8] | 字节 | 是/否 | 二进制数据、非 UTF-8 数据 |
参阅 references/string-types.md,了解类型转换(.to_string() 与 .to_owned() 与 .into())、Cow 用法以及 &str 切片安全性(is_char_boundary)。
第 4 部分:内部可变性
Cell、RefCell 与 OnceCell
use std::cell::{Cell, RefCell, OnceCell};
// Cell: only for Copy types, no borrow checking
let counter = Cell::new(0);
counter.set(counter.get() + 1);
// RefCell: for non-Copy types, runtime borrow check (panics on double borrow)
let cache = RefCell::new(HashMap::new());
cache.borrow_mut().insert("k", 42);
// OnceCell: one-time initialization
static CONFIG: OnceCell<Config> = OnceCell::new();
let cfg = CONFIG.get_or_init(|| Config::load());
| 类型 | 线程安全? | 用途 |
|---|---|---|
Cell<T> | 否 | 仅适用于 Copy 类型的简单修改 |
RefCell<T> | 否 | 非 Copy 类型,单线程 |
OnceCell<T> | 否 | 一次性延迟初始化 |
OnceLock<T> | 是 | 一次性延迟初始化,多线程(std 1.70+) |
LazyLock<T> | 是 | 透明的延迟初始化(std 1.80+) |
参阅 references/interior-mutability.md,了解 panic 安全性(RefCell 重复借用)、如何选择 Cell 或 RefCell,以及多线程场景下的 Atomic*。
第 5 部分:Option 和 Result 组合器
Option 组合器
// map: transform inner value
name.map(|n| n.to_uppercase()) // Option<String>
// and_then: chain fallible operations
id.and_then(|i| db.lookup(i)) // Option<User>
// unwrap_or / unwrap_or_else: provide default
port.unwrap_or(8080)
port.unwrap_or_else(|| env::var("PORT").unwrap_or("8080").parse().unwrap())
// ok_or / ok_or_else: convert Option to Result
user.ok_or(Error::NotFound)?
user.ok_or_else(|| Error::UserMissing(id))?
// filter, is_some, is_some_and
age.filter(|&a| a >= 18)
opt.is_some_and(|x| x > 0)
// transpose: swap Option<Result> → Result<Option>
let x: Result<Option<i32>, _> = Some("5").parse::<i32>().map(Some);
Result 组合器
// ? for propagation (prefer over explicit match)
fn load() -> Result<Config, Error> { Ok(parse(file_read()?)?) }
// map_err: convert error type
file_read().map_err(|e| Error::Io(e))?
// map: transform success value
parse(s).map(|n| n * 2)
// and_then: chain fallible
validate(input).and_then(process)
// or_else / or: fallback on error
primary.or_else(|_| fallback())
常见模式
| 模式 | 代码 |
|---|---|
| 尝试解析,失败时回退到默认值 | s.parse().unwrap_or(default) |
| 出错时提前返回 | let x = result?; |
| 将 Option 转换为 Result | opt.ok_or(Error::Missing)? |
| 收集所有 Result | results.collect::<Result<Vec<_>, _>>() |
| 全部尝试,返回第一个成功结果 | `opts.into_iter().find_map( |
参阅 references/option-result-combinators.md,了解完整的组合器表和重构模式。
第 6 部分:I/O 流
Trait 层级
Read ────┐
├─ BufRead (adds buffering, lines())
Write ───┘
Seek (random access)
如何选择
| 需求 | 使用 |
|---|---|
| 从来源读取字节 | impl Read(File、Cursor、stdin) |
| 缓冲读取(按行读取、读取至指定位置) | impl BufRead(使用 BufReader 包装) |
| 向目标写入字节 | impl Write(File、stdout、Vec) |
| 随机访问 | impl Seek(File) |
| 异步 I/O | tokio::io::AsyncRead/AsyncWrite(rust-concurrency) |
use std::io::{BufRead, BufReader, Read, Write};
use std::fs::File;
let f = File::open("log.txt")?; // impl Read
let reader = BufReader::new(f); // wrap for BufRead
for line in reader.lines() { // BufRead::lines
println!("{}", line?);
}
参阅 references/io-streams.md,了解 Cursor<Vec<u8>>、错误处理(io::Result),以及同步与异步之间的转换。
第 7 部分:迭代器
如何选择
| 需求 | 使用 |
|---|---|
| 借用元素 | .iter() → Iterator<Item = &T> |
| 可变借用 | .iter_mut() → Iterator<Item = &mut T> |
| 消耗元素 | .into_iter() → Iterator<Item = T> |
| 索引和值配对 | .iter().enumerate() |
| 筛选 | .filter(|x| *x > 0) |
| 转换 | .map(|x| x * 2) |
| 展平 | .flat_map(|x| x.iter()) |
| 收集到 Vec | .collect::<Vec<_>>() |
| 收集到 HashMap | .collect::<HashMap<_, _>>()(来自 (K, V) 元组) |
| 查找第一个匹配项 | .find(|x| *x == 5) |
| 判断任意/全部 | .any(|x| *x > 0)、.all(|x| *x > 0) |
| 分组/求和 | .sum::<i32>()、.product()、.fold(0, |a, b| a + b) |
// Borrowed iteration is the default
let v = vec![1, 2, 3];
for x in &v { /* x: &i32 */ } // .iter()
for x in &mut v { /* x: &mut i32 */ }
for x in v { /* x: i32, v consumed */ }
参阅 references/iterators.md,了解自定义迭代器(实现 Iterator)、惰性求值和零成本抽象。
第 8 部分:标准库并发
标准库提供线程、通道和同步原语。关于异步内容,请参阅 rust-concurrency。
线程
use std::thread;
use std::time::Duration;
let handle = thread::spawn(|| {
thread::sleep(Duration::from_millis(500));
"result"
});
let r = handle.join().unwrap(); // wait, get result
作用域线程(Rust 1.63+)— 无需 'static 即可借用
let mut data = vec![1, 2, 3];
thread::scope(|s| {
s.spawn(|| { data[0] += 1; });
s.spawn(|| { data[1] += 1; });
}); // all threads joined here; data borrow ends
mpsc 通道
use std::sync::mpsc;
use std::thread;
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
tx.send(42).unwrap();
});
println!("{}", rx.recv().unwrap());
同步原语
| 原语 | 用途 |
|---|---|
Mutex<T> | 独占锁、同步内部可变性 |
RwLock<T> | 多读者、少写者 |
Arc<T> | 原子引用计数 |
Barrier | 在某个时点同步多个线程 |
Once | 一次性初始化 |
Condvar | 等待/通知 |
Atomic*(AtomicUsize、AtomicBool 等) | 无锁计数器、标志 |
参阅 references/std-concurrency.md,了解 Arc<Mutex<T>> 模式、毒化恢复,以及何时应转向 Tokio。
第 9 部分:时间、路径、进程
时间
use std::time::{Duration, Instant, SystemTime};
let start = Instant::now();
expensive_op();
println!("took {:?}", start.elapsed()); // Duration
let five_secs = Duration::from_secs(5);
let mixed = Duration::new(5, 500_000_000); // 5.5s
let now = SystemTime::now();
let since_epoch = now.duration_since(SystemTime::UNIX_EPOCH)?;
Duration— 时间跨度(无特定时刻)Instant— 单调时刻,用于测量经过的时间SystemTime— 墙上时钟时间,用于时间戳(可能倒退!)
路径
use std::path::{Path, PathBuf};
let p = Path::new("/usr/bin/foo");
let stem = p.file_stem(); // "foo"
let ext = p.extension(); // "foo" → None; "foo.txt" → "txt"
let joined = PathBuf::from("/usr").join("bin").join("foo");
let parent = p.parent(); // "/usr/bin"
文件系统路径始终使用 Path/PathBuf,不要使用 String。可安全跨平台使用。
进程
use std::process::Command;
let output = Command::new("ls")
.arg("-l")
.arg("/")
.output()?; // waits, returns Output
println!("{}", String::from_utf8_lossy(&output.stdout));
// Stream stdin/stdout
use std::process::Stdio;
let mut child = Command::new("cat")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?;
有关 Command 退出代码、信号处理和 fs 模块(read、write、create_dir、元数据),请参阅 references/process-and-fs.md。
工作流
- 确定需求 — 集合、指针、字符串、I/O、迭代器还是系统接口?
- 应用决策树 — 从上方相关部分中选择
- 检查 MSRV — 某些 API(
OnceLock1.70、LazyLock1.80、作用域线程 1.63)需要较新的稳定版 - 使用组合器组合 — 优先使用
Option/Result链,而不是显式match - 验证 —
cargo check、cargo test、cargo clippy - 移交 — 异步运行时 →
rust-concurrency;不安全代码 →rust-unsafe-ffi;应用层问题 → 领域技能
快速决策
| 问题 | 答案 |
|---|---|
| 默认集合? | Vec<T> |
| 需要键值查找? | HashMap(无序)或 BTreeMap(有序) |
| 共享所有权? | Rc(单线程)或 Arc(多线程) |
| 可变共享状态? | RefCell(单线程)或 Mutex/RwLock(多线程) |
| 字符串参数? | 始终使用 &str |
| 文件路径? | Path / PathBuf |
| 惰性全局变量? | OnceLock(1.70+)或 LazyLock(1.80+) |
| 借用式迭代? | .iter() |
| 双端队列? | VecDeque |
| 优先级队列? | BinaryHeap |
资源
- 集合深入介绍
- 智能指针
- 字符串类型
- Option/Result 组合器
- I/O 流
- 迭代器
- 标准库并发
- 进程和文件系统
- 内部可变性
- 标准库模块索引
examples/golden-stdlib/:一个演练集合、指针、通道和迭代器的 crate