文档章节

Rust基础笔记之浅谈Ownership

junanhonglei
 junanhonglei
发布于 2016/03/16 21:41
字数 1043
阅读 34
收藏 1
点赞 1
评论 0

写在前面

Ownership System是Rust中最独特和吸引人的特性,Rust也是依靠这个特性来实现他的最大的目标:内存安全,所有Rust的开发者都应该详细了解它。
多么浓厚的翻译味道,的确本人学习Rust主要依靠官方的文档(写的很清楚详细),这个系列的文章是我学习Rust的笔记,不完全是翻译官方文档,但大部分内容都是来源于官方文档,但是加上了很多自己的理解、思考和总结,这些笔记呢也都是最基本的概念,暂时并没有深入研究,希望大家在阅读文章的时候能多去看看官方手册,欢迎批评指正和补充。

Ownership(所有权)

Rust有一个非常棒的特点,那就是能在编译的时候检查出大多数安全隐患,这就避免了像C语言一样,编译一切OK,运行时来个Segment Fault,让人不明所以,所以Rust需要一套机制来保证在编译时期发现这些问题,这就是强大的Ownership System,它呢,包含了三个部分:

  • Ownership

  • Borrowing

  • Lifetime

(后面都会说到),这玩意确实不怎么好理解,得慢慢来。


当声明一个变量绑定的时候,即该变量拥有了对应内存区域的所有权,当该变量超出作用域的时候,它所指向的内存就会被释放。
当然,我们可以将它指派给其他的绑定,就像这样:

//the vector allocates space on the heaplet v=vec![1, 2, 3];let v2=v;

如果在新的绑定之后调用原先的变量,就会得到如下错误:

error: use of moved value: `v`

原因是let v2 = v;该语句将v所指向的内存区域移交给(move)了v2,之所以报错,官方文档的原话是:

When we move v to v2, it creates a copy of that pointer, for v2. Which means that there would be two pointers to the content of the vector on the heap. It would violate Rust's safety guarantees by introducing a data race. Therefore, Rust forbids using v after we’ve done the move.

意思就是说,现在有两个指针指向了该内存区域,为了避免数据竞争,Rust是不允许使用move后的源变量。

这里有一个问题就是:如果v2超出了它的作用域之后,还能调用v吗?

let v = vec![1,2,3];    
{    let v2 = v;
}
println!("v[0] is {} ",v[0]);

结果是依然报错:

error: use of moved value: `v`

也就是说当v2超出其作用域后,v2并不会归还其对应的内存区域的所有权。

对于函数而言也会遇到一样的问题:

fn take(v: Vec<i32>) {    // what happens here isn’t important.}let v = vec![1, 2, 3];
take(v);
println!("v[0] is: {}", v[0]);

依然会遇到这样的问题

error: use of moved value: `v`

你可能会觉得好像有的变量绑定就不是这样的,比如:

let v = 1;let v2 = v;
println!("v is {}",v);
println!("v2 is {}",v2);

这段代码就可以正常输出啊。
这是因为x是i32类型的,它实现了Copy的特性,官方文档的原话是:

In this case, v is an i32, which implements the Copy trait. This means that, just like a move, when we assign v to v2, a copy of the data is made. But, unlike a move, we can still use v afterward. This is because an i32 has no pointers to data somewhere else, copying it is a full copy.

之所以上面的代码没有问题,是因为它是一个完全拷贝,连同数据也复制了一份,不存在两个指针指向同一块内存区域的问题,更谈不上数据竞争,所以这段代码并没有Rust的安全机制,自然也就是允许的,这是和move不同的地方。

如果你想在v2之后还想使用v,可以用如下的方式:

let v = vec![1,2,3];    
let v2 = v;
println!("y[0] is {} ",y[0]);let v = v2; //交回所有权println!("v[0] is {} ",v[0]);

这样的语法是不是很麻烦,有没有办法让v2再超出作用域后自己交回所有权呢?有来看看Borrow的概念吧。


本文转载自:https://segmentfault.com/a/1190000002902842

共有 人打赏支持
junanhonglei
粉丝 8
博文 102
码字总数 39613
作品 0
鄂州
架构师
Swift 5 的蓝图:ABI 稳定

今天凌晨,我看到 Swift 开发小组的现任掌门 Ted Kremenek 贴出了名为「Swift 5: start your engines」的一条 Twitter ,预示着 Swift 5 的开发工作即将展开了。 老实说,Swift 4 的变化不大...

I'm TualatriX ⋅ 2017/11/29 ⋅ 0

通往 Rust 1.0 之路,Mozilla 新的编程语言

Rust 开发者宣布他们正接近发布1.0版本,计划在年底发布1.0的beta版本。如果一切进展顺利,正式版本将在beta测试后发布。在1.0版本之后,未来发布的1.x版本将会向后兼容,现有代码可以不做修...

oschina ⋅ 2014/09/17 ⋅ 26

Rust语言开发基础(七)Rust 特性

这部分是Rust语言的核心部分,掌握起来有一定难度,特别是生命周期部分,让人有Rust的学习曲线陡升的感觉,爬过这座高峰,其它皆坦途。 这部分也是让人觉得Rust语言比其它语言如C/C++等复杂的...

Robinson_L ⋅ 2016/03/25 ⋅ 0

当 Rust 遇上 Fedora

Rust 是什么? Rust 是一种系统编程语言,它运行速度惊人,并且可以避免几乎所有的崩溃、内存区块错误 以及数据竞争。你也许会质疑为什么我们还需要又一种这样的语言,因为已经有很多同类的语...

达尔文 ⋅ 2016/10/21 ⋅ 34

Fn FnMut FnOnce以及move的区别

There are three different "kinds" of closure in Rust, Fn, FnMut, and FnOnce, these differ in that their calling methods take &self, &mut self, and self respectively. This means ......

曾赛 ⋅ 2015/11/07 ⋅ 0

为什么你需要近距离接触 Rust 1.0

在不背离安全或抽象的情况下,拥有极高的运行效率,能预防几乎所有的错误,提供优越的底层控制和性能——这些都是Rust1.0版本做出的承诺,而这仅仅是个开始。 经过几年的迭代改进,Rust编程语...

oschina ⋅ 2015/08/13 ⋅ 16

我用 Rust 重写了博客,谈谈我眼中的 Rust.

前言 我已经学习 Rust 有挺长的一段时间了,一直想用 Rust 来写点东西,但是缺乏好的想法; 有些想法自我感觉良好,但是又没有能力实现 (比如,写一个操作系统?), 所以最后我决 定还是拿我的...

春哥大魔王的博客 ⋅ 06/13 ⋅ 0

回应王垠的《对 Rust 语言的分析》

经常阅读王垠的博客,对里面绝大多数文章的观点都是认同的。但对于《对 Rust 语言的分析》这篇,作为一个已经用了Rust两年多的人,想提出一些不同的看法。 首先,介绍一下我自己的一些项目,...

主线程 ⋅ 2017/11/18 ⋅ 0

2017 我的技术之路:不忘初心,夯实基础

2017 我的技术之路:不忘初心,夯实基础 又一年春去冬来,到了年末盘点的时候,感觉自己今年相较于前两年沉稳了些,也愈能明晰自身的不足;所以本年的主题就定为了不忘初心,夯实基础。今年年...

⋅ 2017/12/27 ⋅ 0

Linux安装rust语言

Linux安装rust语言 海运的博客2017-08-1915 阅读 安装linux 自动安装脚本: 手工选择安装: 点赞 安装linux 作者:海运的博客 个人笔记 原文地址:Linux安装rust语言, 感谢原作者分享。 →L...

海运的博客 ⋅ 2017/08/19 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

中标麒麟(龙芯版)7.0优盘安装

########################################## 制作U盘安装盘: 1.准备U盘: PMON环境下U盘必须格式化成ext3; 昆仑固件环境下可以格式化成ext3,ext4 2.把整个镜像 xxx.iso 复制到U盘下面 3....

gugudu ⋅ 2分钟前 ⋅ 0

老司机写的大数据建模五步走

本文将尝试来梳理一下数据建模的步骤,以及每一步需要做的工作。 01 第一步:选择模型或自定义模式 这是建模的第一步,我们需要基于业务问题,来决定可以选择哪些可用的模型。 比如,如果要预...

gulf ⋅ 11分钟前 ⋅ 0

PacificA 一致性协议解读

PacificA 的 paper 在 08 年左右发出来的,比 Raft 早了 6,7 年。 在 PacificA 论文中,他们强调该算法使用范围是 LAN (Local Area Network),讲白了就是对跨机房不友好。 不管是 ZAB,Raf...

黑客画家 ⋅ 13分钟前 ⋅ 0

盘符图标个性化

设置自己的专属盘符图标 准备ico格式的图片文件一个,在根目录下创建autorun.inf文件 文件内容 [Autorun]icon=logo.ico 重新启动或者插拔U盘即可看到结果...

阿豪boy ⋅ 13分钟前 ⋅ 0

Windows下QQ聊天记录中图片的默认存放位置

Windows下QQ聊天记录中图片的默认存放位置在设置中是没有说明的。 实测位置在:D:\Documents\Tencent Files\974101467\Image 其中: “974101467”为对应的QQ号; “C2C”为个人之间的聊天图...

临江仙卜算子 ⋅ 20分钟前 ⋅ 0

GC 的三种基本实现方式

参考资料《代码的未来》(作者: [日] 松本行弘)。 由于并非本人原著(我只是个“搬运工“),SO 未经本人允许请尽情转载。 另外个人像说明一下这里所说的GC指泛指垃圾回收机制,而单指Jav...

xixingzhe ⋅ 21分钟前 ⋅ 0

Android双击退出

/** * 菜单、返回键响应 */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub if(keyCode......

王先森oO ⋅ 25分钟前 ⋅ 0

idea 整合 vue 启动

刚学习Vue 搭建了一个项目 只能命令启动 Idea里面不会启动 尝试了一下修改启动的配置 如下: 1.首先你要保证你的package.json没有修改过 具体原因没有看 因为我改了这个name的值 就没办法启动...

事儿爹 ⋅ 30分钟前 ⋅ 0

redis在windows环境的后台运行方法

在后台运行,首先需要安装redis服务,命令为 redis-server.exe --service-install redis.windows.conf --loglevel verbose 启动,命令为 redis-server --service-start 停止,命令为 redis-...

程序羊 ⋅ 33分钟前 ⋅ 0

比特币现金开发者提出新的交易订单规则

本周,四位比特币现金的四位开发者和研究员:Joannes Vermorel(Lokad),AmaurySéchet(比特币ABC),Shammah Chancellor(比特币ABC)和Tomas van der Wansem(Bitcrust)共同发表了一篇关...

lpy411 ⋅ 37分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部