目标:装好环境、跑通第一个程序、理解 main、println!、cargo 三件套。
一、环境搭建(动手 5 分钟)
1. 安装 Rust
bash
# Linux / macOS
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Windows:下载 rustup-init.exe 运行
安装后验证:
bash
rustc --version # 编译器版本
cargo --version # 包管理与构建工具版本
2. 两个核心工具的区别
rustc 是编译器,负责把单个 .rs 文件编译成可执行程序,类似 gcc。
cargo 是项目管理工具,负责创建项目、管理依赖、构建、运行、测试,类似 npm 加 make 的组合。
日常开发几乎只用 cargo,rustc 了解即可。
3. 创建第一个项目
bash
cargo new hello_rust
cd hello_rust
cargo run
你会看到目录结构:
hello_rust/
├── Cargo.toml # 项目配置(依赖、元信息)
└── src/
└── main.rs # 入口文件
二、第一段代码解读
rust
fn main() {
println!("Hello, Rust!");
}
逐行拆解:
fn 是定义函数的关键字(function)。
main 是程序入口,每个可执行程序必须有且仅有一个。
() 是参数列表,这里为空。
{ } 是函数体。
println! 是宏(注意末尾的 !),不是函数!它会在编译期展开。
"Hello, Rust!" 是字符串字面量。
; 是语句结束符,Rust 中大部分语句都要分号。
⚠️ 新手最易错点:写成 println(...) 会报错 cannot find function println。记住 ! 是宏的标志。
三、多元化练习题(含答案与解读)
🟢 练习 1(基础):打印多行
要求:让程序输出以下内容
rust
我叫 Rust
我从 2015 年开始稳定
我喜欢安全与速度
参考答案
rust
fn main() {
println!("我叫 Rust");
println!("我从 2015 年开始稳定");
println!("我喜欢安全与速度");
}
解读:每个 println! 自带换行。若想一行内输出多个内容,可用多个 {} 占位符,或用 print! 不换行。
🟡 练习 2(理解宏):占位符 {}
要求:用一个 println! 输出 1 + 1 = 2,其中数字用变量代入。
参考答案
rust
fn main() {
let a = 1;
let b = 1;
println!("{} + {} = {}", a, b, a + b);
}
解读:{} 是占位符,按顺序被后面的参数填充。这是 Rust 格式化输出的基础。参数可以是变量,也可以是表达式(如 a + b)。
🟡 练习 3(调试思维):找出错误
下面代码无法编译,请指出几处错误:
rust
fn main() {
println("Hello")
}
参考答案
2 处错误:
第一处,println 缺少 !,应为 println!。
第二处,语句末尾缺少 ;。
正确写法:
rust
fn main() {
println!("Hello");
}
解读:Rust 编译器报错非常友好,会明确告诉你 "help: use println!" 和 "help: add ;"。学会读编译器提示是 Rust 学习的关键技能。
🔴 练习 4(拓展):转义与原始字符串
要求:输出一行 路径是: C:\Users\rust,分别用转义和原始字符串两种写法。
参考答案
rust
fn main() {
// 方法一:转义反斜杠
println!("路径是: C:\\Users\\rust");
// 方法二:原始字符串 r"..."
println!(r"路径是: C:\Users\rust");
}
解读:
\ 表示一个字面反斜杠。
r"..." 是原始字符串(raw string),内部不处理转义,适合写正则、路径。
🔴 练习 5(综合):自己动手建项目
要求:
- 用 cargo new my_first_app 创建项目
- 修改 main.rs 打印你的名字和今天的日期
- 用 cargo run 运行
- 用 cargo build --release 构建发布版,观察 target/release/ 目录
参考步骤
bash
cargo new my_first_app
cd my_first_app
# 编辑 src/main.rs
cargo run
cargo build --release
ls target/release/
解读:
cargo run 等于编译(debug)加运行。
cargo build 只编译不运行。
--release 开启优化,产物更大但更快,用于正式发布。
🔵 思考题 1:为什么 println! 是宏不是函数?
参考答案
核心原因有三个:
第一,可变参数。println! 可以接受任意数量的参数(println!("{} {}", a, b, c)),而 Rust 的普通函数不支持可变参数。
第二,编译期格式检查。宏在编译期展开,编译器能检查占位符 {} 的数量和类型是否与参数匹配。如果写成函数,检查只能推迟到运行时,出错更晚、代价更高。
第三,零成本抽象。宏展开后直接生成拼接字符串的代码,没有函数调用开销。
解读:Rust 用宏来实现"看起来像语法糖、实际是编译期代码生成"的功能。类似的还有 vec!\[\]、format!、assert!。
🔵 思考题 2:cargo run 和直接 rustc main.rs && ./main 有什么区别?
参考答案
主要区别有四点:
第一,依赖管理。cargo 会自动下载、编译 Cargo.toml 里声明的依赖;rustc 需要手动处理。
第二,目录结构。cargo 把产物放在 target/debug/,源码在 src/;rustc 默认把可执行文件放在当前目录。
第三,配置与缓存。cargo 会缓存已编译的依赖,增量编译;rustc 每次全量编译。
第四,debug 与 release。cargo 用 --release 切换优化模式;rustc 需要手动加 -O 等参数。
解读:cargo 是工程化工具,rustc 是底层编译器。cargo 内部其实也是调用 rustc。小脚本可以用 rustc,实际项目一律用 cargo。
🔵 思考题 3:如果 main 函数返回一个值,会发生什么?
参考答案
main 可以返回 ()(默认)或者实现了 Termination trait 的类型,比如 Result<(), E>。
rust
use std::fs::File;
fn main() -> Result<(), std::io::Error> {
let _f = File::open("不存在.txt")?;
Ok(())
}
返回 Ok(()) 时进程退出码为 0(成功);返回 Err(e) 时,Rust 会打印错误并以非零退出码结束。
解读:这是第 8 课 Result 和错误处理的伏笔。? 运算符会自动向上传播错误,让 main 成为最终的错误收口处。普通的 i32 等类型不能直接作为 main 的返回类型,因为没实现 Termination。
四、知识点总结(第1课)
安装:rustup 管理工具链,cargo 管项目。
入口:fn main() { } 是程序起点。
宏 vs 函数:println! 是宏,带 !;普通函数不带。宏支持可变参数、编译期检查。
语句结束:大多数语句以 ; 结尾。
占位符:{} 按顺序填充参数,参数可以是变量或表达式。
转义:\ 转义反斜杠;r"..." 原始字符串。
Cargo 命令:new / run / build / build --release。日常开发用 cargo,rustc 是底层。
main 返回值:可返回 () 或 Result<(), E>,影响进程退出码。
编译报错:认真阅读 help: 提示,它会教你改。
五、下一课预告
第2课:变量、可变性与常量
· let vs let mut
· 常量 const 与 static
· 变量遮蔽(shadowing)
· 数据类型初探
📌 本课心法:
Rust 的学习曲线陡,但编译器是你的老师。每一条报错都是在教你写更安全的代码。别怕红色,读懂它,你就赢了。