当前位置: 首页 > news >正文

Rust中所有权和作用域及生命周期

在 Rust 中,作用域(Scope)所有权(Ownership) 是保证内存安全的核心机制,它们共同决定了变量的生命周期和内存管理方式,无需垃圾回收即可避免悬垂指针、双重释放等内存问题。

概念含义是否自动触发销毁示例
作用域 (Scope)变量的可访问范围✅ 是{ let x = 1; }
所有权 (Ownership)资源的唯一持有者✅ 是let s = String::from("hi");
生命周期 (Lifetime)引用的有效区间N/A&'a str

作用域

作用域是 一个变量(或引用、资源)在程序中 有效、可访问 的代码范围 ,由一对花括号 {}界定:

  1. 确定性:作用域由代码结构显式界定,编译期即可确定,不存在运行时动态变化。
  2. 自动清理:变量离开作用域时,Rust 会自动调用其drop方法(若实现drop trait,则会调用 drop函数),释放内存或资源(如文件句柄、网络连接等)。
  3. 嵌套性:作用域可以嵌套(内部作用域包含在外部作用域中),内部作用域可访问外部作用域的实体,但外部作用域无法访问内部作用域的实体。
事件发生时机结果
变量绑定let语句执行时内存分配(如需要)
变量可见声明点到作用域结束可在作用域内访问
变量销毁离开作用域时调用 drop释放资源

变量销毁顺序

  1. 后进先出(LIFO):与声明顺序相反
  2. 结构体字段:按声明顺序销毁
  3. 数组元素:从第一个到最后一个

所有权

Rust不使用垃圾回收(GC),而是通过所有权系统在编译期保证内存安全 (在编译时会进行一系列的规则检查,在运行时零开销):

  • 每个值(资源)在任意时刻只有一个所有者(owner);
  • 当所有者离开作用域时,值会被自动销毁;
  • 赋值或传参会移动(move)所有权,除非实现了copy trait。

引用与借用

为避免 频繁的 所有权转移,Rust 提供引用机制:

  • 不可变引用(&T):只读访问,允许多个同时存在;
  • 可变引用(&mut T):可修改数据,同一作用域内仅允许一个。

借用规则:

  • 引用作用域不能超过被引用变量的作用域(防悬垂引用);
  • 同一数据不能同时存在可变和不可变引用。

赋值

赋值会引起两种语义:

  • 复制(Copy)a 仍然可以使用;
    • 隐式浅拷贝:若类型实现 Copy trait(如整数、浮点、布尔、字符、元组中全是 Copy 类型) ,则赋值时为Copy语义,不会转移所有权;
    • Clone(显式深拷贝):会同时复制堆数据;
  • 所有权转移(Move)a 不再有效。

Copy类型

类型类别示例特点
标量类型(scalar)i32, u64, f32, bool, char小且固定大小,在栈上
全是 Copy 类型的元组(i32, i32), (u8, f64, bool)只要里面的每个字段都是 Copy
指针类(少见)*const T, *mut T原生指针)不涉及所有权
函数指针fn(i32) -> i32也是 Copy

非Copy类型

类型类别示例说明
堆分配类型String, Vec<T>, Box<T>包含堆内存指针
动态大小类型&str, [T], Rc<T>内部有引用计数或指针
用户定义结构体若字段中含非 Copy 成员整体就不是 Copy
其他智能指针Rc<T>, Arc<T>, RefCell<T>有运行时管理逻辑

生命周期

生命周期(Lifetime)是编译器用来确保引用始终有效的核心机制。它们解决了"悬垂引用"问题——确保引用不会指向已释放的内存。生命周期是引用有效的作用域范围,由编译器在编译时进行静态分析,不产生运行时开销:** **

  • 引用在使用时是合法的;
  • 不会悬空(dangling reference);
  • 不会同时存在冲突的可变/不可变引用。

生命周期参数用 'a, 'b 等表示(撇号 '声明生命周期参数),用法类似于泛型参数 ( 在大多数情况下,Rust 会自动推断生命周期):

  • 'a 并不改变运行逻辑;
  • 只是告诉编译器:“这些引用之间的关系”。
场景必须明确标注的情况可以省略的情况
结构体包含引用类型的字段(无论多少个)不包含引用字段(无需生命周期参数)
普通函数1. 多个引用参数且返回引用1. 无返回引用
2. 单个引用参数且返回引用
方法1. 返回引用来自外部参数(非 self)
2. 多个外部引用参数且返回引用
1. 返回引用来自 self
2. 无返回引用
Trait / 枚举包含引用类型的关联项或方法参数 / 返回值不包含引用类型的关联项或方法

结构体

当结构体包含引用时,必须为这些引用标注生命周期,以确保结构体的生命周期不超过它所包含的引用的生命周期。

若结构体的多个引用来自不同生命周期,可用多个参数区分

// 两个字段的生命周期不同,分别用'a和'b标注
struct Article<'a, 'b> {content: &'a str, // 内容的生命周期为'asource: &'b str,  // 来源的生命周期为'b
}fn main() {let content = String::from("Rust lifecycle intro");let source = "Wikipedia"; // 字符串字面量,生命周期为'staticlet art = Article {content: &content,source: &source,};// art的生命周期受限于'a(content的生命周期)和'b(source的生命周期)中较短的一个
}

函数

函数的参数或返回值如果是引用类型,可能需要标注生命周期。

省略规则:编译器有3条生命周期推断规则,允许在常见场景中省略显式注解:

  • 每个引用参数获取自己的生命周期参数
fn foo(x: &i32)         // 隐式:fn foo<'a>(x: &'a i32)
fn foo(x: &i32, y: &i32) // 隐式:fn foo<'a, 'b>(x: &'a i32, y: &'b i32)
  • 若只有一个输入生命周期参数,它被赋予所有输出生命周期参数;
fn bar(x: &str) -> &str // 隐式:fn bar<'a>(x: &'a str) -> &'a str
  • 若有多个输入生命周期参数,但其中一个是&self&mut self,则self的生命周期将赋予所有输出周期参数
impl<'a> ImportantExcerpt<'a> {fn announce(&self, announcement: &str) -> &str {// 隐式:fn announce<'b>(&'a self, announcement: &'b str) -> &'a strprintln!("注意:{}", announcement);self.part}
}

必须明确标注的情况:当函数的返回引用可能来自多个输入引用,或编译器无法推断返回引用的来源时,必须手动标注生命周期:

  • 多个输入引用参数,且返回引用
// 正确示例:标注生命周期'a,说明x、y和返回值共享同一生命周期
// 注解'a表示:返回的引用必须来自x或y,且其生命周期不超过x和y中生命周期较短的那个。
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {if x.len() > y.len() { x } else { y }
}

静态生命周期

'static是一个特殊的生命周期,表示引用可以存活到整个程序运行期间。常见:

  • 字符串字面量:存储在程序的只读内存中,生命周期为'static
  • 显式声明为'static的引用(需确保引用的值确实能存活到程序结束,否则会报错)。
http://www.dtcms.com/a/453711.html

相关文章:

  • 外贸网站啥需要掌握在自己手里中企动力手机邮政登录
  • 二维码制作网站有哪些618网络营销策划方案
  • 【论文学习】2025年图像处理顶会论文
  • 【MyBatis】——执行过程
  • 修改配置文件之后,重启edge浏览器收藏夹消失怎么办?
  • 网站推广优化外包公司个人网站设计开题报告
  • 组播实验-IGMP、IGMP Snooping及PIM-DM协议
  • 企业seo网站推广公司wordpress 下载受限
  • 第十二篇:std::shared_ptr和std::weak_ptr:共享所有权与解决循环引用
  • 第十九章:千变万化,随心而动——State的状态艺术
  • Harmony中EventHub实现发布订阅
  • 高效学习方法——知识关联性
  • 教育类网站素材总部在上海的世界500强企业
  • CCF编程能力等级认证GESP—C++6级—20250927
  • libopenssl-1_0_0-devel-1.0.2p RPM 包安装教程(openSUSE/SLES x86_64)​
  • 网站开发栏目需求1仪征网站建设公司哪家好
  • FK 外键上需要创建index 避免 主表update时 的lock
  • 三剑合璧:C++11 lambda、variadic template 与 wrapper 的协奏
  • 空间智能找文献方向
  • 儒枫网网站建设惠州 企业网站建设
  • 基于 GEE 平台用 Sentinel-1 SAR 数据实现山区潜在滑坡检测
  • CSS是什么?—— 网页的“化妆师”
  • cygwin + redis
  • 我也来做外国网站购物苏州新区建网站
  • #智能电饭煲技术开发原理与源代码实现
  • 无人机系统耗电,低功耗管理问题解决方法(chatgpt)
  • 设计网站国外公共建设工程中心网站
  • 第二十章:遍历万象,操作随心——Visitor的访问艺术
  • 找不到或无法加载主类
  • XMedia Recode:音频格式转换