Rust权威指南学习笔记——认识所有权

什么是所有权

1. 所有权规则

  • Rust中的每一个值都有一个对应的变量作为它的所有者。
  • 在同一时间内,值有且仅有一个所有者。
  • 当所有者离开自己的作用域时,它持有的值就会被释放掉。

2. 变量作用域

  • s在进入作用域后变得有效。
  • 它会保持自己的有效性直到自己离开作用域为止。

Rust在变量离开作用域时,会调用一个叫作drop的特殊函数。

3.移动

为了确保内存安全,同时也避免复制分配的内存,Rust在这种场景下会简单地将s1废弃,不再视其为一个有效的变量。因此,Rust也不需要在s1离开作用域后清理任何东西。

let s1 = String::from("hello");
let s2 = s1; println!("{}, world!", s1);

4. 克隆:深拷贝

let s1 = String::from("hello");
let s2 = s1.clone(); println!("s1 = {}, s2 = {}", s1, s2);

5. Copy的trait

let x = 5;
let y = x; println!("x = {}, y = {}", x, y);
// x = 5, y = 5

以上代码没有调用clone,x在被赋值给y后也依然有效,且没有发生移动现象。这是为什么?

  • 一旦某种类型拥有了Copy这种trait,那么它的变量就可以在赋值给其他变量之后保持可用性。
  • 如果一种类型本身或这种类型的任意成员实现了Drop这种trait,那么Rust就不允许其实现Copy这种trait。
  • 一些拥有Copy trait的类型
    • 所有的整数类型,诸如u32。
    • 仅拥有两种值(true和false)的布尔类型:bool。
    • 字符类型:char。
    • 所有的浮点类型,诸如f64。
    • 如果元组包含的所有字段的类型都是Copy的,那么这个元组也是Copy的。例如,(i32, i32)是Copy的,但(i32, String)则不是。

引用与借用

(1)引用

let s1 = String::from("hello");

let len = calculate_length(&s1);

...

fn calculate_length(s: &String) -> usize { // s 是一个指向 String 的引用
s.len()
} // 到这里,s离开作用域。但是由于它并不持有自己所指向值的所有权,
//所以没有什么特殊的事情会发生
  • 这些&代表的就是引用语义,它们允许你在不获取所有权的前提下使用值。
  • 与变量类似,引用是默认不可变的,Rust不允许我们去修改引用指向的值。以下编译出错。
fn main() {
let s = String::from("hello"); change(&s);
} fn change(some_string: &String) {
some_string.push_str(", world");
}

(2)可变引用

  • 首先,我们需要将变量s声明为mut,即可变的。其次,我们使用&mut s来给函数传入一个可变引用,并将函数签名修改为some_string: &mut String来使其可以接收一个可变引用作为参数。
fn main() {
let mut s = String::from("hello"); change(&mut s);
} fn change(some_string: &mut String) {
some_string.push_str(", world");
}
  • 对于特定作用域中的特定数据来说,一次只能声明一个可变引用。

cannot borrow 's' as mutable more than once at a time...

let mut s = String::from("hello"); 

let r1 = &mut s;
let r2 = &mut s;

好处:避免数据竞争。

数据竞争(data race)与竞态条件十分类似,它会在指令满足以下3种情形时发生:

• 两个或两个以上的指针同时访问同一空间。

• 其中至少有一个指针会向空间中写入数据。

• 没有同步数据访问的机制。

(3)悬垂引用

使用拥有指针概念的语言会非常容易错误地创建出悬垂指针。这类指针指向曾经存在的某处内存地址,但该内存已经被释放掉甚至是被重新分配另作他用了。而在Rust语言中,编译器会确保引用永远不会进入这种悬垂状态。假如我们当前持有某个数据的引用,那么编译器可以保证这个数据不会在引用被销毁前离开自己的作用域。

切片

《Rust权威指南》学习笔记——4. 认识所有权的更多相关文章

  1. HTTP权威指南-学习笔记

    目录 HTTP权威指南-学习笔记 HTTP: Web的基础 URL与资源 HTTP报文 连接管理 HTTP结构 Web服务器 代理 缓存 集成点: 网关,隧道及中继 Web机器人 识别,认证与安全 客 ...

  2. JavaScript 权威指南-学习笔记(一)

    本文所有教程及源码.软件仅为技术研究.不涉及计算机信息系统功能的删除.修改.增加.干扰,更不会影响计算机信息系统的正常运行.不得将代码用于非法用途,如侵立删! ## JavaScript 权威指南-学 ...

  3. CSS权威指南学习笔记系列(1)CSS和文档

    题外话:HTML是一种结构化语言,而CSS是它的补充:这是一种样式语言.CSS是前端三板斧之一,因此学习CSS很重要.而我还是菜鸟,所以需要加强学习CSS.这个是我学习CSS权威指南的笔记,如有不对, ...

  4. Hadoop权威指南学习笔记二

    MapReduce简单介绍 声明:本文是本人基于Hadoop权威指南学习的一些个人理解和笔记,仅供学习參考,有什么不到之处还望指出,一起学习一起进步. 转载请注明:http://blog.csdn.n ...

  5. Hadoop权威指南学习笔记一

    Hadoop简单介绍 声明:本文是本人基于Hadoop权威指南学习的一些个人理解和笔记,仅供学习參考,有什么不到之处还望指出.一起学习一起进步. 转载请注明:http://blog.csdn.net/ ...

  6. Hadoop权威指南学习笔记三

    HDFS简单介绍 声明:本文是本人基于Hadoop权威指南学习的一些个人理解和笔记,仅供学习參考.有什么不到之处还望指出,一起学习一起进步. 转载请注明:http://blog.csdn.net/my ...

  7. IDA Pro权威指南学习笔记(一)

    一直不懂逆向,最近刚好不忙,于是学习逆向,用来做笔记,顺便和大家分享交流. 参考书籍<IAD PRO权威指南> 工具: PETools: ETools 是另一款很好的PE文件编辑工具,以前 ...

  8. css权威指南学习笔记 —— css选择器

    1,选择器:选择器的一些基本常用规则基本都记得,w3c上都有,平时也常用,不常用的一些后代选择器经常就忘记了.一些归纳一下后代选择器,加深一下印象: a:子选择器:   p>a  a是直接是p的 ...

  9. maven权威指南学习笔记(五)—— POM

    1. 简介 Archetype插件通过 pom.xml 文件创建了一个项目.这就是项目对象模型 (POM),一个项目的声明性描述. 当Maven运行一个目标的时候,每个目标都会访问定 义在项目POM里 ...

  10. maven权威指南学习笔记(三)——一个简单的maven项目

    目标: 对构建生命周期 (build  lifecycle),Maven仓库 (repositories),依赖管理 (dependency management)和项目对象模型 (Project O ...

随机推荐

  1. Roadblocks

    poj3255 题目: Bessie has moved to a small farm and sometimes enjoys returning to visit one of her best ...

  2. 转码服务serverless探索

    背景 公司目前主要聚焦于视频这个领域,利用视频为媒体.文旅.会议等行业进行赋能. 既然聚焦于视频领域,那么视频转码则是绕不开的话题. 为了降低成本,以及保证产品的核心能力,公司自建了一套转码系统. 转 ...

  3. LeetCode-1719 重构一棵树的方案数

    来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/number-of-ways-to-reconstruct-a-tree 题目描述 给你一个数组  ...

  4. sqlserver生成指定的序列

    WITH numbers AS ( SELECT 1 AS num UNION ALL SELECT num + 1 FROM numbers WHERE num < 30 ) SELECT C ...

  5. unity 音频曲线

    jp--------------- https://techblog.kayac.com/dynamic-waveform-generation-without-audio-clip https:// ...

  6. No.2.2

    空间转换(使用transform属性实现元素在空间的位移.旋转.缩放等效果) 空间:是从坐标轴角度定义的.x.y.和 z三条坐标轴构成了一个立体空间,z轴位置与视线方向相同. 空间转换也叫3D转换(属 ...

  7. Spring、SpringMVC的区别

    Spring是IOC和AOP的容器框架,SpringMVC是基于Spring功能之上添加的Web框架,想用SpringMVC必须先依赖Spring.简单点的话可以将SpringMVC类比于Struts ...

  8. Qt控制台输出显示乱码

    Qt控制台输出显示乱码 https://jingyan.baidu.com/article/ab69b2709aab0b2ca7189f3d.html

  9. vue3 打开页面input框自动获得焦点

    1.需要聚焦的el-input输入框设置ref值: ref="getfcous" <el-input v-model="workorder" ref=&q ...

  10. Java面向对象之instanceof和类型转换

    instanceof instanceof(类型转换):利用此关键字可以判断某一个对象是否是指定类的实例 格式: 对象 instanceof 类 返回boolean型 - 如果某个对象是某个类的实例, ...