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:独占可变引用,仅一份,可修改。
  • \* :手动解引用;.:自动解引用。
  • 借用规则:不可变共享、可变独占,不同时存在,无悬垂引用。
相关推荐
传奇开心果编程3 小时前
【Rust入门练中学】第6课:结构体与方法
开发语言·rust·结构体·编程语言理论·结构体方法·编程通用语言
本地化文档3 小时前
cutile-rs-book-l10n
rust·gpu·nvidia·cuda·sphinx·crowdin
qq_406981036 小时前
大白话rust系列09 函数调用两次有什么错?
开发语言·python·rust
康小旺8 小时前
TypeScript 编译器开始卷 Rust 了:Cloudflare 的 tsrs 到底想干嘛?
rust·typescript
Norna8 小时前
时间轮的 +1,为什么最后只留在顶层
rust
轻舟技术A14 小时前
Rust 重写 Pi:会话启动耗时降 91%,就绪内存少 78%
开发语言·后端·rust
unconditional14 小时前
外部命令改不了你的 shell:sdkm 怎么做到"回车即生效"
rust·开源
程工造Agent15 小时前
从 0 到 1 学 Codex 源码:为什么 let b = a 之后,a 就不能用了?
rust·ai编程
Norna15 小时前
方差怎么会是 −32:nushell math variance 的一次数值修复
rust
JavaPub-rodert15 小时前
王仕宇分享:Oxigraph 是什么?用 Rust + RocksDB 搭一个轻量 RDF/SPARQL 知识图谱数据库
数据库·rust·知识图谱