快速上手
您将学到: 如何安装 Rust 及其工具链、Cargo 构建系统 vs pip/Poetry、IDE 配置、第一个
Hello, world!程序,以及映射到 Python 等效物的基本 Rust 关键字。难度: 初级
安装 Rust
Section titled “安装 Rust”# 通过 rustup 安装(Linux/macOS/WSL)curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# 验证安装rustc --version # Rust 编译器cargo --version # 构建工具 + 包管理器(类似 pip + setuptools 的组合)
# 更新 Rustrustup updateRust 工具 vs Python 工具
Section titled “Rust 工具 vs Python 工具”| 用途 | Python | Rust |
|---|---|---|
| 语言运行时 | python(解释器) | rustc(编译器,很少直接调用) |
| 包管理器 | pip / poetry / uv | cargo(内置) |
| 项目配置 | pyproject.toml | Cargo.toml |
| 锁文件 | poetry.lock / requirements.txt | Cargo.lock |
| 虚拟环境 | venv / conda | 不需要(依赖是按项目的) |
| 格式化工具 | black / ruff format | rustfmt(内置:cargo fmt) |
| linter | ruff / flake8 / pylint | clippy(内置:cargo clippy) |
| 类型检查 | mypy / pyright | 内置编译器(始终开启) |
| 测试运行器 | pytest | cargo test(内置) |
| 文档 | sphinx / mkdocs | cargo doc(内置) |
| REPL | python / ipython | 无(使用 cargo test 或 Rust Playground) |
IDE 配置
Section titled “IDE 配置”VS Code(推荐):
需要安装的扩展:- rust-analyzer ← 必需:IDE 功能、类型提示、自动完成- Even Better TOML ← Cargo.toml 语法高亮- CodeLLDB ← 调试器支持
# Python 等效映射:# rust-analyzer ≈ Pylance(但 100% 类型覆盖,始终开启)# cargo clippy ≈ ruff(但检查正确性,而不仅仅是风格)第一个 Rust 程序
Section titled “第一个 Rust 程序”Python Hello World
Section titled “Python Hello World”# hello.py — 直接运行print("Hello, World!")
# 运行:# python hello.pyRust Hello World
Section titled “Rust Hello World”// src/main.rs — 必须先编译fn main() { println!("Hello, World!"); // println! 是宏(注意那个 !)}
// 构建和运行:// cargo runPython 开发者的关键差异
Section titled “Python 开发者的关键差异”Python: Rust:───────── ─────- 不需要 main() - fn main() 是入口点- 缩进 = 代码块 - 花括号 {} = 代码块- print() 是函数 - println!() 是宏(! 很重要)- 无分号 - 分号结束语句- 无类型声明 - 类型推断但始终已知- 解释型(直接运行) - 编译型(cargo build,然后运行)- 运行时错误 - 大多数错误在编译时创建第一个项目
Section titled “创建第一个项目”# Python # Rustmkdir myproject cargo new myprojectcd myproject cd myprojectpython -m venv .venv # 不需要虚拟环境source .venv/bin/activate # 不需要激活# 手动创建文件 # src/main.rs 已创建
# Python 项目结构: Rust 项目结构:# myproject/ myproject/# ├── pyproject.toml ├── Cargo.toml (类似 pyproject.toml)# ├── src/ ├── src/# │ └── myproject/ │ └── main.rs (入口点)# │ ├── __init__.py └── (不需要 __init__.py)# │ └── main.py# └── tests/# └── test_main.pygraph TD subgraph Python ["Python 项目"] PP["pyproject.toml"] --- PS["src/"] PS --- PM["myproject/"] PM --- PI["__init__.py"] PM --- PMN["main.py"] PP --- PT["tests/"] end subgraph Rust ["Rust 项目"] RC["Cargo.toml"] --- RS["src/"] RS --- RM["main.rs"] RC --- RTG["target/ (自动生成)"] end style Python fill:#ffeeba style Rust fill:#d4edda关键差异:Rust 项目更简单——无
__init__.py、无虚拟环境、无setup.pyvssetup.cfgvspyproject.toml混淆。只有Cargo.toml+src/。
Cargo vs pip/Poetry
Section titled “Cargo vs pip/Poetry”# Python — pyproject.toml[project]name = "myproject"version = "0.1.0"requires-python = ">=3.10"dependencies = [ "requests>=2.28", "pydantic>=2.0",]
[project.optional-dependencies]dev = ["pytest", "ruff", "mypy"]# Rust — Cargo.toml[package]name = "myproject"version = "0.1.0"edition = "2021" # Rust edition(类似 Python 版本)
[dependencies]reqwest = "0.12" # HTTP 客户端(类似 requests)serde = { version = "1.0", features = ["derive"] } # 序列化(类似 pydantic)
[dev-dependencies]# 测试依赖 — 仅在为 `cargo test` 编译时# (不需要单独的测试配置 — `cargo test` 是内置的)常用 Cargo 命令
Section titled “常用 Cargo 命令”# Python 等效 # Rustpip install requests cargo add reqwestpip install -r requirements.txt cargo build # 自动安装依赖pip install -e . cargo build # 始终是"可编辑"python -m pytest cargo testpython -m mypy . # 内置编译器 — 始终运行ruff check . cargo clippyruff format . cargo fmtpython main.py cargo runpython -c "..." # 无等效 — 使用 cargo run 或测试
# Rust 特有:cargo new myproject # 创建新项目cargo build --release # 优化构建(比调试快 10-100 倍)cargo doc --open # 生成并浏览 API 文档cargo update # 更新依赖(类似 pip install --upgrade)Python 开发者的基本 Rust 关键字
Section titled “Python 开发者的基本 Rust 关键字”变量和可变性关键字
Section titled “变量和可变性关键字”// let — 声明变量(类似 Python 赋值,但默认不可变)let name = "Alice"; // Python: name = "Alice"(但 Python 是可变的)// name = "Bob"; // ❌ 编译错误!默认不可变
// mut — 选择加入可变性let mut count = 0; // Python: count = 0(Python 总是可变的)count += 1; // ✅ 因为 `mut` 所以允许
// const — 编译时常量(类似 Python 的 UPPER_CASE 约定,但强制执行)const MAX_SIZE: usize = 1024; // Python: MAX_SIZE = 1024(只是约定)
// static — 全局变量(谨慎使用;Python 有模块级全局变量)static VERSION: &str = "1.0";所有权和借用关键字
Section titled “所有权和借用关键字”// 这些在 Python 中没有等效 — 它们是 Rust 特有的概念
// & — 借用(只读引用)fn print_name(name: &str) { } // Python: def print_name(name: str) — 但 Python 总是传递引用
// &mut — 可变借用fn append(list: &mut Vec<i32>) { } // Python: def append(lst: list) — Python 总是可变
// move — 转移所有权(在 Rust 中隐式发生,Python 从不会)let s1 = String::from("hello");let s2 = s1; // s1 移动到 s2 — s1 不再有效// println!("{}", s1); // ❌ 编译错误:值已移动类型定义关键字
Section titled “类型定义关键字”// struct — 类似 Python 的 dataclass 或 NamedTuplestruct Point { // @dataclass x: f64, // class Point: y: f64, // x: float} // y: float
// enum — 类似 Python 的 enum 但强大得多(可以携带数据)enum Shape { // 没有直接的 Python 等效 Circle(f64), // 每个变体可以持有不同数据 Rectangle(f64, f64),}
// impl — 给类型附加方法(类似在类中定义方法)impl Point { // class Point: fn distance(&self) -> f64 { // def distance(self) -> float: (self.x.powi(2) + self.y.powi(2)).sqrt() }}
// trait — 类似 Python 的 ABC 或 Protocol(PEP 544)trait Drawable { // class Drawable(Protocol): fn draw(&self); // def draw(self) -> None: ...}
// type — 类型别名(类似 Python 的 TypeAlias)type UserId = i64; // UserId = int (或 TypeAlias)控制流关键字
Section titled “控制流关键字”// match — 穷举模式匹配(类似 Python 3.10+ 的 match,但强制执行)match value { 1 => println!("one"), 2 | 3 => println!("two or three"), _ => println!("other"), // _ = 通配符(类似 Python 的 case _:)}
// if let — 解构 + 条件(Python 风格:if (m := regex.match(s)):)if let Some(x) = optional_value { println!("{}", x);}
// loop — 无限循环(类似 while True:)loop { break; // 必须 break 才能退出}
// for — 迭代(类似 Python 的 for,但更常需要 .iter())for item in collection.iter() { // for item in collection: println!("{}", item);}
// while let — 带解构的循环while let Some(item) = stack.pop() { process(item);}可见性关键字
Section titled “可见性关键字”// pub — 公开(Python 没有真正的私有;使用 _ 约定)pub fn greet() { } // def greet(): — Python 中一切都是"公开的"
// pub(crate) — 仅在 crate 内可见pub(crate) fn internal() { } // def _internal(): — 单下划线约定
// (无关键字)— 对模块私有fn private_helper() { } // def __private(): — 双下划线名称修饰
// 在 Python 中,"私有"是君子协定。// 在 Rust 中,私有由编译器强制执行。🏋️ 练习:第一个 Rust 程序(点击展开)
挑战:创建一个新的 Rust 项目并编写程序:
- 声明一个类型为
&str的变量name(您的名字) - 声明一个从 0 开始的可变变量
count - 使用
for循环从 1..=5 递增count并打印"Hello, {name}! (count: {count})" - 循环后,使用
match表达式打印 count 是奇数还是偶数
🔑 答案
cargo new hello_rust && cd hello_rustfn main() { let name = "Pythonista"; let mut count = 0u32;
for _ in 1..=5 { count += 1; println!("Hello, {name}! (count: {count})"); }
let parity = match count % 2 { 0 => "even", _ => "odd", }; println!("Final count {count} is {parity}");}关键收获:
let默认不可变(需要mut来改变count)1..=5是包含性范围(Python 的range(1, 6))match是返回值的表达式- 无
self,无if __name__ == "__main__"— 只有fn main()