[易学易懂系列|rustlang语言|零基础|快速入门|(3)]

· · 1371 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

易学易懂系列|rustlang语言|零基础|快速入门|(3)

今天我们来讲讲rust最难,也是最重要的概念:

Ownership,Borrowing,Lifetimes

首先我们来看看:ownership(所有权)

我们来看看下面的代码:

 let a = [1, 2, 3];

 let b = a;

 println!("{:?} {:?}", a, b); *// [1, 2, 3] [1, 2, 3]*

 let a = vec![1, 2, 3];

 let b = a;

 println!("{:?} {:?}", a, b); *// Error; use of moved value: `a`*

我们把这两段代码,放在vscode里去build.

第一段代码没有问题,第二段代码报错。

vscode会报错信息:

  println!("{:?} {:?}", a, b); // Error; use of moved value: `a`|                                       ^ value borrowed here after move

编译器已经告诉我们原因:value borrowed here after move

也就是说a对原来数据的所有权已经move(移动)给b,这时再访问a的值。编译器就会报告你犯了一个严重错误。

我们用简单的图示来说明:

image-20191122090758916.png

如图,a原来有本书,现在给了b.

image-20191122090928487.png

那现在,这本书就在b手上了。b拥有这本书。

对应代码就是:

let a = vec![1, 2, 3];

let b = a;// a把数据给b.

那这个时候,a已经没有对数据的所有权,就访问不了数据,编译器就报错。

那为什么第一段代码,又不报错呢?

原来,rust中分两种数据类型:

1.基本数据类型: 如:bool(布尔),char(字符),integer(整数),floating(浮点),arrays(数组),tuples(元组),slice(切片),字符串(str),函数指针(functions)

对基本类型的详细说明 可以参考英文教程:

https://learning-rust.github.io/docs/a6.variable_bindings,constants_and_statics.html

或中文参考:http://wiki.jikexueyuan.com/project/rust/primitive-types.html

2.非基本类型:

即除基本类型外的其它类型,一般为引用类型。

那rust对这两种类型会分别不同处理:

对基本类型,rust会对原来a的数据复制,并把复制数据赋值给b,并把原始数据的所有权状态 设置为“已复制( copied )”状态。

对非基本类型,rust会把原来a的数据移动,并把原始数据赋值给b,并把原始数据的所有权状态 设置为“已移动( moved )”状态。

针对这两种处理模式,rust内部又定义为两种类型:复制类型(Copy type ),移动类型( Move type

但这里还要注意一点,对于函数指针类型,一般情况下为移动类型( Move type ),但如果它实现以下接口:

core::marker::Copy trait

则它也是复制类型,执行复制的模式。

以上,就是所有权的基本概念和要点。

其实,我们重新思考多线程中的数据安全,rust的这种设计,是非常合理的。

(关于线程安全的问题,我之前写过java的高并发与锁的原理系列,见:https://www.cnblogs.com/gyc567/p/11014782.html

首先,rust定义数据初始化动作为绑定,并且默认为不可变,如下:

let a =9;

a=10;//error

第二行代码 a=10;是会报错的。为什么?因为它是不可变的,如果要改变,就要把它定义为mut(可变),如下:

let mut a =9;

a=10;//correct

所以,rust的设计哲学就是默认所有线程操作都是不安全的。那所有数据默认为不可变,在多线程环境下,就是相当于所有线程都可以共享数据,是线程安全的,因为数据是不变的。

那回到上面的所有权的概念,复制类型(Copy type )就相当于数据共享,可以共享复制数据,但禁止写。移动类型( Move type )就相当于独占锁,线程拥有这把“锁”,才能访问数据,否则报错。

以上,希望对你有用。

如果遇到什么问题,欢迎加入:rust新手群,在这里我可以提供一些简单的帮助,加微信:360369487,注明:博客园+rust

本人精通java高并发,DDD,微服务等技术实践,以及python,golang技术栈。 本人姓名郭莹城,坐标深圳,前IBM架构师、咨询师、敏捷开发技术教练,前IBM区块链研究小组成员、十四年架构设计工作经验,《区块链核心技术与应用》作者之一, 现有成熟团队提供区块链开发相关业务(公链,交易所,钱包,Dapp,智能合约)。 工作微信&QQ:360369487,交易所开发与区块链钱包开发业务,加我注明:博客园+开发,想学习golang和rust的同学,也可以加我微信,备注:博客园+golang或博客园+rust,谢谢!


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:

查看原文:[易学易懂系列|rustlang语言|零基础|快速入门|(3)]

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1371 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传