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

【Rust中级教程】1.9. 所有权(简单回顾):所有权的核心思想、如何实现`Copy` trait、值的删除(丢弃)、值删除的顺序

喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)

这篇文章只对所有权进行简单回顾,想要看完整的所有权系统阐述见 【Rust自学】4.2. 所有权规则、内存与分配。
请添加图片描述

1.9.1. 所有权的核心思想

Rust内存模型的核心思想是所有值都只有一个所有者。也就是说只有一个位置(通常是作用域来) 负责释放每个值。

这种效果是通过借用检查器实现的,如果值移动了(赋值新变量、推到Vec上、置于堆内存上等),其所有者也变成新的位置了。

所有者实际上就是内存上的一个位置,数据所在的位置就是值的所有者。移动指的是数据从一个位置转移到另一个位置,新的位置就是数据的所有者。

但是有些类型不执行这种规则:如果值的类型实现了Copy trait,那么在重新赋值时不是移动而是复制。也就是把值复制一份放到新的位置。

1.9.2. 如何实现Copy trait

实现Copy trait的类型必须可以按位(bit)来复制值。

能实现Copy trait的类型自然不包括:

  • 含有non-copy类型的类型
  • 如果一个类型在其值被丢弃时,必须执行某些特殊的资源释放操作

为什么呢?
想象一下,如果Box<T>实现了Copy trait,进行赋值:box1 = box2,这时候这两个变量都认为自己在堆内存上有一块专属于自己的空间,所以当它们走出作用域时,它们都会尝试释放那块内存,导致双重释放(double free),其危害在 【Rust自学】4.2.5. 内存和分配 中已作介绍,可以点击链接查看,这里不做重复。

1.9.3. 值的删除(丢弃)

当值不再被需要时,其所有者会将其删除。

值的删除(或者叫丢弃)发生于值走出作用域时。类型会递归地将其所包含的值删除。比如说我们要删除一个复杂类型的变量,会导致需要删除很多值。

但Rust不会发生多次删除同一个值的情况(因为所有权设计)。变量若含有对其他值的引用(不拥有该值),当变量被删除时,其它的值不会被删除。

这样说可能难理解,那我们看一个简单的例子:

fn main() {  
    let x1 = 42;  
    let y1 = Box::new(x1);  
  
    {  
        let z = (x1, y1);  
    }  
      
    let x2 = x1;  
}
  • x1i32类型,y1Box<i32>类型,指向x1
  • 使用{}创建了一个新的作用域,在这个小作用域里创建了z
  • z是元组类型,其值是(x1, y1)x1i32类型,实现了Copy trait,所以x是把自己的值复制了一份给zy1Box<i32>,没有实现Copy trait,所以它不能复制值,而是把所有权转移给了z
  • 离开了小作用域之后又使用了一次x1x1此时还保持有效在于x是把自己的值复制了一份给z,自身仍然保持有效。
  • y1在给z赋值之后就失效了,因为它把所有权转移给了z

1.9.4. 值删除的顺序

  • 变量(包括函数的参数)按照相反的顺序进行删除。
    在上面的例子中,y1是先声明的,z是后声明的。所以在删除时会先删z再删y1

  • 嵌套的值按照源代码的顺序进行删除。
    在上面的例子中,z在被删除时会按照先删除x1,再删除y1的顺序

注意:Rust暂时不允许在单个值内进行自我引用

相关文章:

  • 第1章大型互联网公司的基础架构——1.6 RPC服务
  • python利用jenkins模块操作jenkins
  • 七、Java常用API(2)
  • [特殊字符] C语言中打开和关闭文件的两种方法:标准库 VS 系统调用
  • layui怎么请求数据
  • 红队视角出发的k8s敏感信息收集——日志与监控系统
  • 【机器学习】向量化使得简单线性回归性能提升
  • 计算机网络知识速记 HTTPS的工作流程
  • 《Stable Diffusion绘画完全指南:从入门到精通的Prompt设计艺术》 第六章
  • Windows 安装 GDAL 并配置 Rust-GDAL 开发环境-1
  • Unity Shader示例 6: 卡渲基础 - 描边 + 着色
  • 地基Spring中bean生命周期和设计模式
  • 介绍cherrypick
  • 【第1章:深度学习概览——1.6 深度学习框架简介与选择建议】
  • 面试题总结
  • 安装vite报错Install for [ ‘create-vite@latest‘ ] failed with code 1
  • 本地 Ollama 部署 Deepseek R1 并使用 Spring AI Alibaba 构建 Chat 应用示例
  • K8s学习总结
  • Langchain对管道操作符|的重构实现链式流程
  • nodejs 038: Js Worker线程消息传递 Worker.postMessage() Worker.postMessage()
  • 夜读丨庭院春韵
  • 以军称若停火谈判无进展,将大幅扩大加沙军事行动
  • 读科学发展的壮丽史诗,也读普通人的传奇
  • “十四五”以来少数民族发展资金累计下达边疆省区252亿元
  • 委员呼吁提高政府机构电话号码准确性,辽宁阜新回应
  • 习近平在中共中央政治局第二十次集体学习时强调,坚持自立自强,突出应用导向,推动人工智能健康有序发展