上海陆家嘴某头部私募的中频组用了七年的 C++ 报单 / 回测框架, 这一周决定把对接券商 CTP 柜台的协议适配层用 Rust 重写。组里资深工程师拿到任务的第一天敲了四条命令:装工具链、新建项目、构建、运行。九十秒后磁盘上多了一个二进制文件并打印了一行字。同样的循环在 C++ Fundamentals (3.4.1) 里要写 CMakeLists.txt、调 clang、写 Conan 清单引 fmt 与 Catch2、手工补 .gitignore。Cargo 把五个工具的工作折成了一个, 而本课你将熟悉的循环, 正是接下来整个 Rust 子学科里你每天都会敲的循环。
三个工具, 三句话讲清
rustup 是工具链管理器 (toolchain manager): 在 stable / beta / nightly 三个 channel 之间切换, 安装 rustfmt / clippy / rust-analyzer / rust-src 等组件, 管理交叉编译目标。你大约每月才会敲一次 rustup——升级或加组件时。
cargo 是构建 / 测试 / 运行 / 依赖 / 打包 的总调度 (orchestrator), 也是你每天会敲的命令:cargo check 类型检查, cargo build 编译, cargo run 执行, cargo test 跑测试, cargo fmt 格式化, cargo clippy 静态检查, cargo doc 生成文档。C++ 世界里要 CMake + Conan + clang-format + clang-tidy + Doxygen 五件套, Rust 里只有 Cargo 一件。
rustc 是编译器本体 (compiler)。你几乎不会直接调用——Cargo 替你调——但编译错误信息前缀 error[E0382]: ... 就来自 rustc, 所以当代码第一次跑不通的时候你会认得这个名字。记住三个名字, 出问题时就知道往哪查。
用 rustup 安装
Linux 与 macOS 用一条命令搞定。下面是 Fenced shell 块: rustup 一键安装外加版本核对。
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustc --version
cargo --version
国内网络访问官方源较慢, 可设置环境变量改用中科大 / RsProxy 镜像: RUSTUP_DIST_SERVER=https://rsproxy.cn 与 RUSTUP_UPDATE_ROOT=https://rsproxy.cn/rustup。Cargo 拉 crate 时也建议在 ~/.cargo/config.toml 中加 [source.crates-io] replace-with = "rsproxy", 这两件事配齐基本不会再因为网络问题卡住。Windows 学员先装 WSL2 (wsl --install -d Ubuntu) 再走 Linux 路径——本模块不教 MSVC 路径下的 Rust。安装脚本会把 ~/.cargo/bin/ 写入 shell PATH, 默认接受即可。新开一个 shell 用两条 --version 命令验证, 应该看到 rustc 1.7x.0 (... 2026) 与 cargo 1.7x.0 这样的输出。然后 rustup default stable 一次固定 channel, rustup component add rustfmt clippy rust-analyzer 一次装齐日常组件。nightly 通道本模块用不上, 留到 3.5.3 讲 portable_simd 时再启用。
用 cargo new 起项目
选一个工作目录, 执行 cargo new hello。Cargo 会写四样东西: hello/Cargo.toml (清单, manifest)、hello/src/main.rs (二进制入口)、hello/.gitignore (其中列入了 target/)——以及隐含的第四样: target/ 目录, 首次构建时才出现。生成的 Cargo.toml 是四节短文:
[package]
name = "hello"
version = "0.1.0"
edition = "2021"
[dependencies]
edition 这一行最关键。Rust 通过版次 (edition) 演进——2015 / 2018 / 2021 / 2024——而版次是 per-crate 而非 per-toolchain 的。固定 edition = "2021" 意味着你这份源代码在任何足够新的编译器上都按同一套语法和惯用法编译。本模块全程目标都是 edition = "2021"。2024 版次已经发布, 但其新引入的特性在本课程范围内不使用。
cargo new 生成的 src/main.rs 是经典的 Hello, World:
fn main() {
println!("Hello, world!");
}
fn main() 声明程序入口——无返回类型, 隐含返回 unit 类型 () (空元组)。println! 是宏 (macro), 末尾的 ! 就是宏调用的标志 (lesson 2 解释这件事为什么重要); 它把格式化字符串和换行符打到标准输出。分号结束一条语句。三行就是整个程序。Lesson 2 再把这三行之间的语言细节补齐。
日常 Cargo 循环
从项目根目录起的五条子命令:
cargo new hello
cd hello
cargo check
cargo build
cargo run
cargo build --release
cargo run --release
cargo check 解析、类型检查、借用检查整个 crate, 但不生成二进制——是确认代码编得过的最快方式, 通常比一次完整的 cargo build 快四到五倍, 因为跳过了 codegen 阶段。当你的编辑器里跑着 rust-analyzer LSP 时, 你会几乎每改几下就敲一次 cargo check。
cargo build 产出调试构建, 二进制位于 target/debug/hello: 优化级别 0, 调试符号打开, 编译快, 运行慢。cargo run 等同于 cargo build 加上立即执行——这就是日常驱动命令。
cargo test (本课不细讲, lesson 5 会专门讲) 会另外编一个测试二进制, 跑所有 #[test] 标注的函数并汇报通过 / 失败。
cargo doc --open 把 /// 文档注释渲染成 HTML 并在浏览器中打开; cargo clean 删掉 target/ 重新构建。
debug 与 release 两种 profile
你每天会出入的两种构建:
cargo build 隐含 --profile dev: 优化级别 0, 调试符号打开, 编译快, 运行慢, 产物在 target/debug/hello。
cargo build --release 显式 --profile release: 优化级别 3, LTO 默认关 (可配), 调试符号关闭, 编译慢, 运行快, 产物在 target/release/hello。
对数值密集型代码, release 比 debug 通常快 5–50 倍——拿 debug 跑 benchmark 是范畴错误, 第一天就要把这条规则刻进肌肉记忆: 迭代用 debug; 任何耗时测量、任何性能声明、任何生产运行都用 release。切换方式就是在子命令后加 --release: cargo run --release、cargo test --release、cargo bench (release 隐含)。
在调试器中运行
工具链自带 rust-gdb (macOS 上是 rust-lldb): gdb / lldb 的薄包装, 预加载了 Rust 的 pretty-printer, 让 Vec<T> / String / Option<T> 在 print 时显示成可读形式。针对你的 hello 二进制, 最小会话长这样:
rust-gdb ./target/debug/hello
(gdb) break hello::main
(gdb) run
(gdb) next
(gdb) continue
(gdb) quit
二进制的 main 位于一个以 crate 命名的模块内, 这就是断点目标写作 hello::main 而不是 main 的原因。macOS 学员把首行换成 rust-lldb ./target/debug/hello, 用 b hello::main 替代 break, 其余四条在 lldb 中一致。这一节不是 gdb 教程——那属于调试器手册——而是要让你看到: 刚装好的工具链里已经有了一个会读 Rust 运行时布局的调试器。后续四课大多时候靠 cargo run 就够了; 当二进制出问题, 直接 rust-gdb, 无需额外学习。
通往后续课程的过渡
到此你已经有了一套可工作的「编译—运行—测试」循环和一个调试器。Lesson 2 把 fn main() 与右花括号之间的语言补齐——量化开发者反射性要用到的基本类型、控制流、模式匹配、函数定义规则。Lesson 3 引入所有权 (ownership) 与借用 (borrowing), 这是把 Rust 与 C++ 区分开的唯一一条最承重的概念。Lesson 4 搭建复合类型工具箱: 结构体 (struct)、枚举 (enum)、trait, 以及 Option<T> / Result<T, E> 错误处理范式。Lesson 5 收尾——模块系统、多文件 Cargo 项目、依赖、单元测试布局, 把本模块整套训练落到位。
参考阅读: 《Rust 程序设计语言》中文版 (kaisery.github.io/trpl-zh-cn) 第 1 章「入门指南」与第 2 章「猜数游戏」; course.rs 的「Rust 圣经」中 Cargo 与 rustup 章节; rustcc.cn 的国内镜像配置指南。一句行业说明: 国内字节跳动、PingCAP (TiDB) 蚂蚁链、部分私募与中频桌已在用 Rust 替换 C++ 写新的低延迟基础设施; 本课程把 Rust 放进核心轨道, 就是为了对齐 T+1 后这一波系统更替的工程实情。
练习
Exercise
拿本课的 hello 项目: (a) 用 cargo build 出一个 debug 二进制, 报告 Cargo 把它写到了哪条路径; (b) 用 cargo build --release 出一个 release 二进制, 报告写到了哪条路径; (c) 用 ls -l target/debug/hello target/release/hello 对比两个文件大小, 报告哪个更大、大约几倍; (d) 分别 cargo run 与 cargo run --release 运行, 报告输出有无差异 (应当没有——同一段程序在两种 profile 下打同一句话); (e) 把 main 里加一行 let _ = 1; 后跑 cargo check, 报告 target/debug/hello 是否被更新。
提示
提示
cargo check 根本不产出二进制——它在类型检查 / 借用检查之后就停下。target/debug/hello 的 mtime 由上一次 cargo build 决定。