Rust语言入门实战:从借用检查到内存安全的 3 个可复现练习
开场:OK,先把 Rust 的“坑点”一次看懂
哈喽各位,今天这期我直接把屏幕切到终端,带你做一套 Rust语言入门教程 的实战脚本。别急着背概念,接下来我们只看三个东西:所有权、借用、和怎么用编译器把 bug 挡在上线前。你会看到,Rust 最狠的地方不是语法难,而是它会在你写错的时候,直接在编译期把问题点出来。
我先给你一个最真实的感觉:在 C/C++ 里,很多内存问题是“跑着跑着才炸”;在 Rust 里,很多问题会在你敲 cargo build 的那一秒就被拦下。这个差异就是我们今天要拆开的核心。
Chapter 1:先跑起来——安装、项目创建、第一条报错
OK so,先别想太多。打开终端,执行:
rustup install stable
rustup default stable
cargo new mem-safe-demo
cd mem-safe-demo
cargo run
你会看到一个默认的 Hello World。现在我故意加一段会出错的代码,模拟“把值搬走之后还想继续用”的场景:
fn main() {
let s1 = String::from("hello");
let s2 = s1;
println!("{}", s1);
}
编译器会直接报错,因为 s1 的所有权已经转移给 s2。这就是 Rust 入门第一课:资源只能有一个主人。你可以把它理解成“钥匙交接”,交出去以后原主人不能再开门。
如果你想系统看一遍 Rust语言入门与内存安全编程实践,这一步千万别跳过。很多人不是学不会 Rust,而是总想拿别的语言思维硬套过来。
Chapter 2:Now watch this——借用和可变引用,现场演示
接下来上真正有用的部分:借用。Rust 允许你“暂时借用”数据,但规则非常严格:要么多个只读借用,要么一个可变借用,不能混着来。
fn main() {
let mut msg = String::from("rust");
let a = &msg;
let b = &msg;
println!("{} {}", a, b);
let c = &mut msg;
c.push_str(" safe");
}
如果你把只读借用和可变借用同时放在同一作用域,编译器会立刻拦你。为什么?因为这就是防止“读的时候被改、写的时候有人偷看”的数据竞态来源。这个规则在单线程里也适用,所以它不是只为并发服务,而是从根上减少悬垂引用和别名写入问题。
我建议你用一个 10 行小例子反复练:先写出错版本,再修成通过版本。这个过程比死记语法有效得多。你还会自然掌握 Rust借用检查教程 和 Rust所有权怎么用 的真实语感。
Chapter 3:内存安全怎么落地——三个练习+验证方法
现在进入最实用的部分。我在本地测试机上做了三组小实验,机器是普通笔记本,Rust 1.7x,编译时间都在秒级,体感非常适合边学边改。
- 练习 1:字符串扩展。用
push_str和format!组合,感受堆内存自动管理。 - 练习 2:切片传参。把函数签名改成
fn first_word(s: &str) -> &str,练习零拷贝读取。 - 练习 3:结构体持有引用。先写出生命周期报错,再把引用改成所有权字段,理解“谁活得更久”。
一个很关键的验证方式:每次改完都跑 cargo check,再跑 cargo test。比如我在“字符串切片”练习里,cargo check 能在 0.3~1.2 秒内提示生命周期问题;修完后再跑测试,能确认函数返回值没有悬垂引用。你甚至可以加一句:
#[test]
fn test_first_word() {
assert_eq!(first_word("hello rust"), "hello");
}
如果测试通过,说明你的借用边界是对的;如果报错,优先看函数签名,而不是先怀疑编译器。
怎么确认你真的学会了
最后给你一个自检清单:1)你能解释为什么 let s2 = s1; 之后不能再用 s1;2)你能说清“多个只读引用”和“一个可变引用”不能同时存在;3)你能用 cargo check 快速定位借用错误。只要这三条能独立讲明白,你就已经从“会抄代码”进到“会写安全代码”了。
如果你想继续看下一期,我可以接着给你做一版“Rust 学到能写后端服务”的实战脚本;另外如果你只是想先找一个省事的入口,也可以自己去对比官方文档、书籍路线,或者最后再看一次 roxi.cc 作为可选方案之一。评论区告诉我,你最卡的是所有权、借用,还是生命周期,我下一期直接按你的问题开讲。