Rust 入门
Rust 是注重安全和性能的系统编程语言。
这页适合作为“第一次系统接触 Rust 的起步页”。真正容易卡住的地方通常不是语法,而是所有权、借用、错误处理和 Cargo 工作流这几块没有一起建立起来。
什么时候值得学 Rust
Rust 特别适合下面这些方向:
- 需要性能、并发安全和内存安全的工具或服务
- 想写 CLI、后端服务、网络程序、系统工具
- 希望把一部分高性能模块嵌入现有项目
- 想要比 C/C++ 更稳的低层开发体验
如果你现在只是想快速写脚本、自动化或数据处理,往往先用 Python、Node.js 会更快;Rust 更适合在“正确性 + 性能 + 可维护性”都重要时投入。
安装
# Windows(推荐 rustup)
winget install Rustlang.Rustup
# 或
scoop install rustup
# Linux/macOS
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# 验证
rustc --version
cargo --version
# 更新
rustup update
Cargo 项目管理
cargo new myproject # 新建项目
cargo new mylib --lib # 新建库
cargo build # 编译
cargo build --release # 发布编译
cargo run # 编译并运行
cargo test # 运行测试
cargo check # 快速检查(不生成二进制)
cargo fmt # 格式化
cargo clippy # Lint 检查
推荐学习顺序
比较稳的顺序通常是:
- 先学变量、函数、结构体、枚举和
match - 再学所有权、借用、生命周期的直觉
- 接着学
Result、Option和错误处理 - 然后把
cargo check、fmt、clippy用顺 - 最后再进入异步、Trait、泛型和工程化
不要一开始就冲 Tokio、宏和复杂生命周期,先把小程序写顺最重要。
Cargo.toml
[package]
name = "myproject"
version = "0.1.0"
edition = "2024"
[dependencies]
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
reqwest = { version = "0.12", features = ["json"] }
基础语法
// 变量(默认不可变)
let name = "Domi";
let mut count = 0; // 可变
count += 1;
// 函数
fn add(a: i32, b: i32) -> i32 {
a + b // 最后一个表达式作为返回值
}
// 结构体
struct User {
name: String,
age: u32,
}
impl User {
fn new(name: &str, age: u32) -> Self {
Self { name: name.to_string(), age }
}
fn greet(&self) -> String {
format!("Hi, I'm {} ({})", self.name, self.age)
}
}
所有权与借用
// 所有权转移
let s1 = String::from("hello");
let s2 = s1; // s1 不再可用
// 借用(引用)
fn print_len(s: &str) {
println!("{}", s.len());
}
// 可变借用
fn push_str(s: &mut String) {
s.push_str(" world");
}
新手理解所有权的实用心法
- 一个值同一时刻只能有一个所有者
- 读数据优先借用
&T - 要修改时再用
&mut T - 能传
&str就别急着传String
写 Rust 时,很多报错并不是“编译器太严格”,而是在提醒你:数据到底归谁管、会不会被同时修改、离开作用域后还会不会被继续引用。
错误处理
use std::fs;
// Result 类型
fn read_file(path: &str) -> Result<String, std::io::Error> {
fs::read_to_string(path)
}
// ? 操作符
fn process() -> Result<(), Box<dyn std::error::Error>> {
let content = fs::read_to_string("config.toml")?;
println!("{}", content);
Ok(())
}
// match 处理
match read_file("data.txt") {
Ok(content) => println!("{}", content),
Err(e) => eprintln!("Error: {}", e),
}
实战建议
- 应用入口层可以用
anyhow - 库代码更适合定义明确错误类型
- 能返回
Result就不要随手unwrap() - 调试阶段可以
expect("清晰报错"),上线前尽量减少无保护崩溃点
枚举与模式匹配
enum Command {
Start,
Stop,
Send(String),
}
fn handle(cmd: Command) {
match cmd {
Command::Start => println!("Starting"),
Command::Stop => println!("Stopping"),
Command::Send(msg) => println!("Sending: {}", msg),
}
}
先从这几类小项目练手
- 文件整理或重命名工具
- 简单命令行 Todo / 记账 / 下载器
- 读取配置文件并输出结果的小 CLI
- 调一个 HTTP API 并保存 JSON 的小程序
这几类项目足够小,又能让你把 Cargo、错误处理、序列化和模块拆分一起练到。
常用 Crate
| Crate | 说明 |
|---|---|
| serde | 序列化/反序列化 |
| tokio | 异步运行时 |
| reqwest | HTTP 客户端 |
| clap | CLI 参数解析 |
| anyhow | 错误处理 |
常见坑
一遇到借用报错就想“硬修”
先别急着加生命周期。更常见的正确解法通常是:
- 缩小变量作用域
- 拆小函数
- 改成借用而不是转移所有权
- 把需要长期持有的数据改成更清晰的结构
cargo run 很顺,一到工程化就乱
建议固定养成这套节奏:
cargo check
cargo fmt
cargo clippy
cargo test
把这四步当成日常工作流,代码质量会稳定很多。
依赖越加越多
Rust 生态很强,但也容易“为了一个小需求引入大依赖”。上线前建议回头看一遍依赖是否真的必要。
延伸阅读
参考链接
- Rust Book — 官方教程
- Rust by Example — 示例学习
- crates.io — 包仓库
- Rustlings — 练习题