| name | rust-std |
| description | Rust 标准库技能。提供 Rust 标准库的完整参考,包括常用模块、类型、trait、函数等。TRIGGER when: 用户使用标准库功能、查询标准库 API、需要标准库代码示例、或需要了解标准库最佳实践时触发。SKIP: 非标准库相关的 Rust 开发。 |
Rust 标准库技能
本技能提供 Rust 标准库的完整参考,基于 Standard Library Documentation。
触发条件
当用户执行以下操作时触发此技能:
- 使用标准库功能
- 查询标准库 API
- 需要标准库代码示例
- 了解标准库最佳实践
跳过条件
以下情况不触发此技能:
常用模块
std::collections
use std::collections::{HashMap, HashSet, BTreeMap, BTreeSet, VecDeque, LinkedList};
let mut map = HashMap::new();
map.insert("key", "value");
let value = map.get("key");
let mut set = HashSet::new();
set.insert(1);
set.contains(&1);
let mut btree = BTreeMap::new();
btree.insert(1, "a");
btree.insert(2, "b");
let mut deque = VecDeque::new();
deque.push_back(1);
deque.push_front(2);
deque.pop_front();
std::fs
use std::fs::{self, File, OpenOptions};
use std::io::{self, Read, Write, BufReader, BufWriter};
let content = fs::read_to_string("file.txt")?;
fs::write("file.txt", "content")?;
let file = File::open("file.txt")?;
let reader = BufReader::new(file);
for line in reader.lines() {
println!("{}", line?);
}
let mut file = OpenOptions::new()
.append(true)
.open("file.txt")?;
writeln!(file, "new line")?;
fs::create_dir_all("path/to/dir")?;
for entry in fs::read_dir(".")? {
let entry = entry?;
println!("{}", entry.path().display());
}
std::path
use std::path::{Path, PathBuf};
let path = Path::new("/tmp/file.txt");
println!("文件名: {:?}", path.file_name());
println!("扩展名: {:?}", path.extension());
println!("父目录: {:?}", path.parent());
println!("是否存在: {}", path.exists());
println!("是否文件: {}", path.is_file());
println!("是否目录: {}", path.is_dir());
let mut path = PathBuf::new();
path.push("src");
path.push("main.rs");
let path = Path::new("/tmp").join("file.txt");
std::io
use std::io::{self, Read, Write, BufRead, BufReader, BufWriter, stdin, stdout};
let mut input = String::new();
stdin().read_line(&mut input)?;
stdout().write_all(b"hello")?;
let reader = BufReader::new(stdin());
let writer = BufWriter::new(stdout());
let mut content = String::new();
File::open("file.txt")?.read_to_string(&mut content)?;
std::thread
use std::thread;
use std::time::Duration;
let handle = thread::spawn(|| {
for i in 1..10 {
println!("hi number {} from the spawned thread!", i);
thread::sleep(Duration::from_millis(1));
}
});
handle.join().unwrap();
let builder = thread::Builder::new()
.name("worker".to_string())
.stack_size(32 * 1024);
let handle = builder.spawn(|| {
println!("Thread name: {:?}", thread::current().name());
}).unwrap();
std::sync
use std::sync::{Arc, Mutex, RwLock, mpsc, Barrier};
let counter = Arc::new(Mutex::new(0));
let counter_clone = Arc::clone(&counter);
let handle = thread::spawn(move || {
let mut num = counter_clone.lock().unwrap();
*num += 1;
});
let lock = Arc::new(RwLock::new(5));
let lock_clone = Arc::clone(&lock);
let r1 = lock.read().unwrap();
let r2 = lock.read().unwrap();
let mut w = lock.write().unwrap();
*w += 1;
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
tx.send("hello").unwrap();
});
let received = rx.recv().unwrap();
std::time
use std::time::{Duration, Instant, SystemTime};
let start = Instant::now();
let elapsed = start.elapsed();
println!("耗时: {:?}", elapsed);
let five_seconds = Duration::from_secs(5);
let ten_millis = Duration::from_millis(10);
thread::sleep(five_seconds);
let now = SystemTime::now();
let since_epoch = now.duration_since(SystemTime::UNIX_EPOCH)?;
println!("自 Unix 纪元以来: {} 秒", since_epoch.as_secs());
std::env
use std::env;
let path = env::var("PATH")?;
let home = env::var("HOME").unwrap_or_default();
env::set_var("MY_VAR", "value");
let args: Vec<String> = env::args().collect();
for arg in args {
println!("{}", arg);
}
let current_dir = env::current_dir()?;
let temp_dir = env::temp_dir();
常用类型
String vs &str
let mut s = String::new();
let s = String::from("hello");
let s = "hello".to_string();
s.push_str(" world");
s.push('!');
let s: &str = "hello";
let s: &str = &string[..];
let s: String = "hello".to_string();
let s: &str = &string;
Vec
let mut v: Vec<i32> = Vec::new();
let v = vec![1, 2, 3];
v.push(4);
v.pop();
v.insert(0, 0);
v.remove(0);
v.retain(|&x| x > 2);
v.sort();
v.sort_by(|a, b| b.cmp(a));
v.sort_unstable();
let pos = v.binary_search(&3);
let pos = v.iter().position(|&x| x == 3);
let slice = &v[1..3];
Option 和 Result
let some: Option<i32> = Some(42);
let none: Option<i32> = None;
let value = some.unwrap_or(0);
let value = some.unwrap_or_default();
let value = some.unwrap_or_else(|| expensive_computation());
let value = some.expect("值不存在");
let ok: Result<i32, String> = Ok(42);
let err: Result<i32, String> = Err("error".to_string());
let value = ok.unwrap_or(0);
let value = ok.unwrap_or_default();
let value = ok.expect("值不存在");
let mapped = some.map(|x| x * 2);
let filtered = some.filter(|&x| x > 10);
let flatmapped = some.and_then(|x| Some(x * 2));
Iterator
let v = vec![1, 2, 3, 4, 5];
let doubled: Vec<i32> = v.iter().map(|x| x * 2).collect();
let evens: Vec<&i32> = v.iter().filter(|&&x| x % 2 == 0).collect();
let sum: i32 = v.iter().sum();
let product: i32 = v.iter().product();
let max = v.iter().max();
let min = v.iter().min();
let count = v.iter().count();
let result: i32 = v.iter()
.filter(|&&x| x % 2 == 0)
.map(|&x| x * 2)
.sum();
for (i, val) in v.iter().enumerate() {
println!("{}: {}", i, val);
}
let names = vec!["Alice", "Bob"];
let ages = vec![25, 30];
let people: Vec<_> = names.iter().zip(ages.iter()).collect();
常用 Trait
Display 和 Debug
use std::fmt;
struct Point {
x: f64,
y: f64,
}
impl fmt::Display for Point {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({}, {})", self.x, self.y)
}
}
impl fmt::Debug for Point {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Point")
.field("x", &self.x)
.field("y", &self.y)
.finish()
}
}
let p = Point { x: 1.0, y: 2.0 };
println!("{}", p);
println!("{:?}", p);
Clone 和 Copy
#[derive(Clone, Copy)]
struct Point {
x: f64,
y: f64,
}
let p1 = Point { x: 1.0, y: 2.0 };
let p2 = p1;
let p3 = p1.clone();
From 和 Into
struct Celsius(f64);
struct Fahrenheit(f64);
impl From<Celsius> for Fahrenheit {
fn from(c: Celsius) -> Self {
Fahrenheit(c.0 * 9.0 / 5.0 + 32.0)
}
}
let c = Celsius(100.0);
let f: Fahrenheit = c.into();
let f = Fahrenheit::from(c);
Default
#[derive(Default)]
struct Config {
width: u32,
height: u32,
fullscreen: bool,
}
let config = Config::default();
let config = Config {
width: 1920,
..Default::default()
};
最佳实践
- 使用
&str 而非 String:作为函数参数时更灵活
- 使用
Vec<T> 而非数组:动态大小更实用
- 使用
Option 和 Result:而非 null 或 panic
- 使用迭代器:比手动循环更简洁高效
- 使用
impl Trait:作为返回类型避免装箱
- 使用
Cow<str>:避免不必要的字符串克隆
常见陷阱
- 字符串编码:Rust 字符串是 UTF-8,不能直接索引
- 所有权转移:注意函数参数的所有权
- 借用检查器:理解可变和不可变借用的规则
- 迭代器惰性:迭代器是惰性的,需要消费才会执行
- 锁的死锁:注意 Mutex/RwLock 的使用顺序