Rust所有权与引用:核心要点速记

一、所有权三大规则(必背)

  1. 每个值都有唯一所有者
  2. 同一时间只能有一个所有者
  3. 所有者离开作用域,值自动销毁(drop)

二、赋值行为:Copy / Move

1. Copy 类型(栈数据)

  • 赋值 / 传参:位拷贝,复制值

  • 原变量保留有效

  • 类型:i32/u8/f64/bool/char/&T/&str/全Copy元组数组

    let a = 10;
    let b = a; // Copy
    println!("{} {}", a, b); // 正常

2. 非 Copy 类型(堆数据)

  • 赋值 / 传参:所有权移动 Move

  • 原变量失效

  • 类型:String/Vec/Box/自定义结构体等

    let s1 = String::from("hello");
    let s2 = s1; // Move
    // println!("{}", s1); // 报错:borrow of moved value

三、引用与借用(Borrowing)

借用 = 获取引用,不转移所有权

1. 不可变引用 &T(共享引用)

  • 可同时存在多个

  • 只读,不可修改

  • 语法:&变量

    let s = String::from("hi");
    let r1 = &s;
    let r2 = &s;
    println!("{} {}", r1, r2); // 合法

2. 可变引用 &mut T(独占引用)

  • 同一时间只能有一个

  • 可读、可修改

  • 原变量必须是 mut

  • 不可与不可变引用同时存在

    let mut s = String::from("hi");
    let r = &mut s;
    r.push_str(" rust"); // 可修改

四、解引用 * 与自动解引用(.)

1. 手动解引用 *

  • &T 是引用,*引用 拿到原始值

    let x = 10;
    let p = &x;
    assert_eq!(*p, 10); // *p 解引用

    let mut x = 10;
    let p = &mut x;
    *p = 20; // 通过可变引用修改原值

2. 自动解引用(. 运算符)

  • Rust 对 .自动解引用 ,无需手动写 *

  • s.len() 等价于 (*s).len()

    let s = &String::from("hello");
    s.len(); // 自动解引用 &String → String

规则:

变量.方法 → Rust 自动套用 &/*/&mut 匹配类型

五、引用 / 解引用 与 Copy 的关系

  • &T 本身是 Copy 类型

    引用赋值是拷贝引用,不是移动。

    let a = 10;
    let r1 = &a;
    let r2 = r1; // Copy,r1、r2都有效

  • 对非 Copy 类型的引用:

    引用本身可 Copy,但底层数据不可 Copy

    let s = String::from("abc");
    let r1 = &s;
    let r2 = r1; // 拷贝引用,没问题
    // let s2 = s; 才是 Move

六、借用三大黄金规则

  1. 要么 多个不可变引用 &T ,要么 一个可变引用 &mut T,不可共存。
  2. 引用不能悬垂(dangling),不能指向已销毁的值。
  3. 可变引用独占、排他,保证线程安全与无数据竞争。

七、Copy 与借用的选择

  • Copy 类型:直接传值,简单高效。

  • 非 Copy 类型 :必须用 &T / &mut T 借用,避免所有权转移。

    // Copy:传值
    fn add(a: i32, b: i32) -> i32 { a + b }

    // 非Copy:传引用
    fn len(s: &String) -> usize { s.len() }


极简一句话

  • 所有权:值有主人,离开作用域销毁。
  • Copy:栈类型,赋值拷贝,原值保留。
  • Move:堆类型,赋值移走所有权,原值失效。
  • &T:共享只读引用,可多份,Copy。
  • &mut T:独占可变引用,仅一份,可修改。
  • \* :手动解引用;.:自动解引用。
  • 借用规则:不可变共享、可变独占,不同时存在,无悬垂引用。
相关推荐
星栈7 小时前
Dioxus 多页面怎么做:`dioxus-router`、嵌套路由、`Outlet` 和页面组织,一篇给你讲顺
前端·rust·前端框架
Rust研习社2 天前
组合真的优于继承吗?为什么 Rust 和 Go 都拥抱组合舍弃继承?
后端·rust·编程语言
红尘散仙3 天前
想写一个像样的终端 App?试试把 React 的开发体验搬进 Rust TUI
前端·rust
vivo互联网技术3 天前
从 Web 到桌面:基于 Tauri 2.0 + Vue 3 打造 vivo 线下门店「大头贴」拍照体验系统
前端·rust
Rust研习社3 天前
这 8 个 Rust 学习资源值得每个新手收藏起来
后端·rust·编程语言
星栈4 天前
10 分钟跑起第一个 Dioxus 应用:`dx` CLI、`rsx!` 和热更新好不好用
前端·rust·前端框架
望眼欲穿的程序猿4 天前
读取芯片内部温度传感器
嵌入式硬件·rust
望眼欲穿的程序猿4 天前
ADC 模拟电压采集
嵌入式硬件·rust
codexu_4612291874 天前
NoteGen 里一条记录如何变成 Markdown
前端·笔记·rust·tauri
Rust研习社4 天前
Rust 错误处理的黄金搭档:一个定义错误,一个传播错误
后端·rust·编程语言