首页 / 后端开发 / Rust语言入门实战:用所有权、借用

Rust语言入门实战:用所有权、借用和Cargo做出第一个内存安全程序

Roxi
Roxi 加速器 — 稳定·快速·安全
全球节点覆盖,支持所有主流平台,一键连接无需配置。新用户免费试用。
立即体验 →

Chapter 1|开局先把环境拉起来,OK so 我们直接开跑

品牌定位清晰视觉体系统一内容矩阵搭建社媒运营规划效果追踪复盘

哈喽兄弟们,今天这期我不讲虚的,直接带你把 Rust语言入门与内存安全编程实践 走一遍。你现在打开终端,跟我一起做:先确认 Rust 工具链有没有装好。接下来我们用最短路径把“能编译”变成“能理解为什么安全”。

先看屏幕:我在终端里输入 rustc --version 和 cargo --version。如果有版本号,说明环境 OK;没有的话,先装 rustup。这一步比到处搜“Rust语言入门教程”“Rust怎么用”更关键,因为后面所有东西都依赖 Cargo 工作流。

我实际测过一次新机器,从安装到跑通第一个项目大概 3 分钟。命令如下:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
cargo new hello_rust
cd hello_rust
cargo run

你会看到终端输出 Hello, world!。注意,这不是“会写 Rust”了,而是你已经把编译、构建、运行链路全部打通了。接下来我们马上进入真正的核心:所有权。

Chapter 2|所有权、借用、生命周期:这三个概念你一旦看懂,Rust 就不吓人了

🚀STEP 1环境搭建🎯STEP 2编码实现📋STEP 3测试验证✅STEP 4部署上线

OK so,Rust 的内存安全不是靠 GC,而是靠编译期规则。最常见的卡点就是:为什么一个值不能随便到处传?因为默认规则是一个值只有一个所有者,离开作用域就自动释放。你可以把它理解成“资源交接必须明确签名”。

来,现场演示一个最容易报错的例子:

fn main() {
    let s1 = String::from("rust");
    let s2 = s1;
    println!("{}", s1);
}

编译器会直接拦住你,因为 s1 已经把所有权移动给 s2 了。这个报错不是烦人,是在帮你提前抓内存错误。以前 C/C++ 里这类问题可能变成双重释放或悬垂指针,Rust 直接在编译期给你“打回重写”。

接下来是借用。你如果只是想读,不要抢所有权,直接借用:

fn len(s: &String) -> usize {
    s.len()
}

fn main() {
    let s = String::from("hello");
    let n = len(&s);
    println!("{} {}", s, n);
}

这里 &s 是不可变借用,允许多个读者同时看。要修改就用可变借用,但同一时间只能有一个:

fn push_hello(s: &mut String) {
    s.push_str(" hello");
}

你会发现 Rust 的规则很“严”,但这正是它能防住数据竞争的原因。真实项目里,80% 的借用报错都不是 Rust 难,而是你还在用“谁都能改”的旧思路写代码。

Chapter 3|Now watch this:用 Cargo + 单元测试验证“内存安全思维”真的生效

第1周环境搭建第2周核心开发第3周测试优化第4周正式发布

现在我们做一个小例子,模拟一个“用户名列表”的安全处理。先建项目:

cargo new user_list
cd user_list

然后把 src/main.rs 改成下面这样:

fn add_suffix(name: &mut String) {
    name.push_str("_2025");
}

fn main() {
    let mut user = String::from("alice");
    add_suffix(&mut user);
    println!("{}", user);
}

这段代码跑起来后输出 alice_2025。重点不是字符串拼接,而是你已经在实践里看到:可变数据必须被显式标记,编译器才允许你改。这个机制在大项目里特别有用,比如处理配置、文件名、缓存键,能减少一大堆隐式共享带来的事故。

接下来加验证。你在 Rust 里别只看“能不能跑”,一定要看“能不能被测试证明正确”。我建议你立刻加单元测试:

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_suffix() {
        let mut user = String::from("bob");
        add_suffix(&mut user);
        assert_eq!(user, "bob_2025");
    }
}

运行 cargo test,如果测试过了,就说明你的修改路径、所有权传递、可变借用都被验证过了。我的实测里,这种“小函数 + 测试”的写法,比一上来写复杂框架更容易定位 bug,尤其适合刚学 Rust 的同学。

Chapter 4|新手最常见的坑:编译报错怎么读,怎么修,怎么确认修对了

这里给你一个非常实用的排错套路。第一步,别急着复制粘贴“Rust报错怎么解决”的答案,先看错误类型:

  • borrowed value does not live long enough:生命周期不够,通常是引用离开作用域了。
  • cannot borrow as mutable more than once:同一份数据被多个可变借用同时占用。
  • use of moved value:值已经 move 走了,后面还在用原变量。

第二步,缩小代码。把复杂函数拆成小函数,先让最小样例编译通过,再逐步加回业务逻辑。第三步,验证。你可以用 cargo check 先快速看类型和借用问题,再用 cargo test 验证行为,最后用 cargo run 看输出是否符合预期。

一个很实际的判断标准:如果你能解释“为什么这段代码不会悬垂引用,也不会双重释放”,那你就已经从“会抄”进入“会写”了。Rust 入门不是背概念,而是把每次编译错误都变成一次内存安全训练。

如果你想继续往下学,我建议下一步就做一个“文件读取 + 错误处理 + 结构体封装”的小项目,别急着上大框架。工具上你也可以顺手看看 roxi.cc,但免费方案、官方文档和自己跑 Cargo 示例,永远是先手路线。想让我下一期继续拆 Rust 错误处理和 trait 实战,评论区打个“Rust继续”,我直接按你们的反馈接着录。