Rust核心概念

这期我们来唠唠 Rust 的"核心五大护法",这几个概念是 Rust 世界的地基,理解它们之后,你再看 Rust 就像"武林秘籍看目录",豁然开朗。我会从"前端视角"来比喻,结合 JS/TS 帮你建立联系。


🥇 所有权(Ownership)------Rust 的"内存保安队长"

在 JS 里,你从来没管过内存,new 也好,数组也好,变量用完就等 GC 回收。但 Rust 没 GC,它靠所有权系统来"自动管理内存"。

通俗讲:

在 Rust 里,每块内存只会有一个"所有者变量"。当所有者变量离开作用域,这块内存就自动释放。

举个例子:

rust 复制代码
fn main() {
    let s1 = String::from("hello");
    let s2 = s1;  // s1 把所有权给了 s2,自己就不能用了
    println!("{}", s1); // ❌ 编译报错:s1 已被移动
}

就像 JS 里的变量 s1 = 'hello';你把它"转手给了 s2",但 Rust 会说:"那 s1 就不能用了哈,我要保证你不会用到无效数据"。

编译期强制你安全编程,这就是 Rust 的牛逼之处。


🥈 借用(Borrowing)------变量"出借",但不能"转让"

那你可能说:"我不想把变量完全交出去,只是借它用一下。"这时候就轮到 Rust 的"借用"机制了。

类比 JS:

js 复制代码
function double(arr) {
  return arr.map(x => x * 2);
}

你传的是个引用,对吧?Rust 里也能借用变量,不转移所有权:

rust 复制代码
fn double(arr: &Vec<i32>) {
    for x in arr {
        println!("{}", x * 2);
    }
}

fn main() {
    let v = vec![1, 2, 3];
    double(&v);  // 借用 v,不移动所有权
    println!("{:?}", v); // ✅ OK,v 还能用
}

Rust 区分:

  • &T:不可变借用,多个可以共存
  • &mut T:可变借用,只能有一个

核心思想:你要么多个读者,要么一个作者,不能又读又写,这样就不会数据冲突。


🥉 生命周期(Lifetimes)------借用的"生死时限"

这听起来吓人,其实是为了解决一个问题:你借的东西,不能比原来活得久。

想象下这个 JS 场景:

js 复制代码
let result;
{
  const temp = "hello";
  result = temp;  // temp 出作用域就挂了,但你还在用 result
}
console.log(result);  // ❌ 潜在问题

Rust 编译器会捕捉这种情况,它要你声明:这个借用能活多久

rust 复制代码
fn get_first<'a>(s: &'a str) -> &'a str {
    &s[0..1]
}

'a 就是生命周期标注,它告诉编译器:传进来的引用,返回值的生命周期不能超过它。

你平时用编译器推断就够了,出问题再显式标注。


🟦 匹配模式(match)------比 switch-case 高级一百倍

JS 有 switch-case,Rust 有 match,但它不仅能匹配值,还能解构、匹配类型、绑定变量,非常强。

rust 复制代码
fn main() {
    let x = Some(5);
    match x {
        Some(1) => println!("one"),
        Some(n) => println!("value is {}", n),
        None => println!("none"),
    }
}

像是类型 + 模式匹配的结合体,有点像 JS 里的:

js 复制代码
const x = { type: 'Some', value: 5 };
switch (x.type) {
  case 'Some': console.log(x.value); break;
  case 'None': console.log('none'); break;
}

但 Rust 写法更简洁,特别适合和枚举/错误处理配合使用


🟥 枚举 + 错误处理(Option / Result)------告别 null、try-catch 的新姿势

Rust 没有 nullundefined 这些让人崩溃的玩意儿。取而代之的是:

1. Option<T> 表示可能有值,也可能没值:

rust 复制代码
let name: Option<String> = Some("Tom".to_string());

match name {
    Some(n) => println!("Hello, {}", n),
    None => println!("No name"),
}

2. Result<T, E> 表示可能成功,也可能失败(比如文件读取、网络请求):

rust 复制代码
fn divide(a: i32, b: i32) -> Result<i32, String> {
    if b == 0 {
        Err("Cannot divide by zero".to_string())
    } else {
        Ok(a / b)
    }
}

fn main() {
    match divide(10, 2) {
        Ok(val) => println!("Result: {}", val),
        Err(e) => println!("Error: {}", e),
    }
}

这种做法好在哪?

  • 编译器强制你"必须处理错误"
  • 再也不会有"调用了 null 的 toString 报错"这种事

是不是很像 TS 的 EitherOption 泛型类型,但更原生、更好用?


总结:核心概念速查表

概念 通俗解释 JS 类比
所有权 谁负责释放内存 没有 GC,要自己守规则
借用 引用变量但不转让 像引用参数,JS 默认传引用
生命周期 借用变量活多久 闭包/作用域变量别用晚了
匹配模式 花式 switch-case 解构 + 类型判断的组合拳
Option / Result 安全处理空值和错误 告别 null、try-catch 的未来式

相关推荐
小小小小宇1 分钟前
React 中 useMemo 和 useCallback 源码原理
前端
Trae首席推荐官4 分钟前
Trae 版本更新|支持自定义智能体、MCP等,打造个人专属“AI 工程师”
前端·trae
木三_copy4 分钟前
前端截图工具--html2canvas和html-to-image的一些踩坑
前端
小桥风满袖6 分钟前
Three.js-硬要自学系列7 (查看几何体顶点位置和索引、旋转,缩放,平移几何体)
前端·css·three.js
kim__jin9 分钟前
Vue3 使用项目内嵌iFrame
前端
独立开阀者_FwtCoder21 分钟前
# 一天 Star 破万的开源项目「GitHub 热点速览」
前端·javascript·面试
天天扭码32 分钟前
前端进阶 | 面试必考—— JavaScript手写定时器
前端·javascript·面试
梦雨生生1 小时前
拖拉拽效果加点击事件
前端·javascript·css
前端Hardy1 小时前
第2课:变量与数据类型——JS的“记忆盒子”
前端·javascript
冴羽1 小时前
SvelteKit 最新中文文档教程(23)—— CLI 使用指南
前端·javascript·svelte