文章图片
笔记说明
这是我的Rust笔记集 , 是记录我学习Rust中比较难以理解(我难以理解的)东西 , 并不是完全的Rust教程 。 如果你有幸看到这篇文章的错误 , 请多多指正 , 谢谢!
我的环境:rustc 1.57.0 (f1edd0429 2021-11-29)
什么是声明周期
Rust生命周期是Rust中比较难以理解的概念(我觉得不是难以理解 , 而是难以使用) , 我不知道是不是Rust中独有的概念 , 但是在Java和Go中 , 我确实没有看到相似的内容 。
那么什么是Rust的生命周期 , 其实一句话就可以概括:表明这个对象可以存活的范围 。
生命周期的主要目标就是为了防止悬空引用 。
Rust的生命周期标记大多时候都是隐式的 , 不用开发人员手动声明 。
比如下面的代码:
我们定义了一个lifecycle()函数 , 当前代码是不能通过编译的 , 编译的时候会抛出:`x` does not live long enough 这个错误 。
那我们来分析一下这段程序 , 变量 ref_x 声明的位置在“作用域a”里面 , 那么ref_x可以存活到lifecycle()函数结束 。 变量 x 在 作用域b 中 , 作用域b 小于 作用域a(b作用域在第14行就结束了) , 但是第16行还在使用ref_x (如果你将16行给删除 , 那么是可以正常编译和运行的 , 因为编译器会检测到ref_x在第14行之后并没有使用 , 不会造成安全隐患) 。
我们都知道Rust的变量会在作用域结束的时候释放内存 , x 在 作用域b 结束的时候就会将内存释放掉 。 这个时候
ref_x还是引用的x的内存地址 , 那么这就会造成悬垂指针 , 这对于安全著称的Rust来说当然是不可原谅的 , 所以Rust编译器就会抛出这个异常(还是那句话 , 你删除第16行就可以编译成功) 。
Rust的借用检查器
Rust有个借用检查器 , 会检查你的引用是否有效 。 如果超过了生命周期 , 那么就会编译失败 。 上面就是非常典型的案例 。 如下 , 我将Rust的声明周期标记给写出来(注意:这个不能通过编译 , 只是为了展示) , 这样更加直观 。
我们可以看见生命周期a 大于 生命周期 b , 我们将b 赋值给 a , 那么通过Java类比 , 就是父类转子类(逆变 , 这个后面再说 , 理解了这个就很容易理解Rust的生命周期) , 如果类型不兼容就会GG 。 为什么说b(小的生命周期)是父类 , 因为按照一般的开发思维来理解 , 父类(作用域b)包含的东西都要少一些 , 子类的东西要丰富一些(比如子类自己新增的方法或者字段) , 那么a的作用域大于b(a内容比b多一些) , 是不是a就是子类 , b是父类 。 [ps:我这种白话我觉得理解起来可能更适合大多数人:)
【生命周期|Rust笔记:Rust生命周期-1】下一篇文章我就会开始深入我当时学习时的坑(也不能叫坑 , 就是我当时不理解的地方) , 做个笔记 。
- 特斯拉|生命安全至上!复旦教授称不要尝试L2级别以上自动驾驶
- 生命周期|独立站应该怎么做,才能提高转化率?从提高独立站的页面加载速度开始!
- 华为|悔不当初!家里这些电器用完千万要拔插头,不然简直拿生命开玩笑
- 周期饶过谁?台积电不会一直“赢”
- 生命最后的浪漫是什么梗 生命最后的浪漫是什么意思
- 生命科学|2021年度生命科学十大进展出炉
- 急!石化退休员工生命垂危,寻找A型血小板捐献者
- 早期的地球对生命来说非常可怕
- Google|从网红变长红,新品如何穿越周期的成长?
- 人民群众生命|网安民警:全天候“巡逻”虚拟世界,守护网络清朗安全