今天我们来讲讲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`
| ^valueborrowedhereaftermove
编译器已经告诉我们原因:value borrowed here after move
也就是说a对原来数据的所有权已经move(移动)给b,这时再访问a的值。编译器就会报告你犯了一个严重错误。
我们用简单的图示来说明:
如图,a原来有本书,现在给了b.
那现在,这本书就在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 ),但如果它实现以下接口:
则它也是复制类型,执行复制的模式。
以上,就是所有权的基本概念和要点。
其实,我们重新思考多线程中的数据安全,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技术栈。
本人精通java高并发,DDD,微服务等技术实践,以及python,golang技术栈。
本人名字郭莹城,坐标深圳,前IBM架构师、咨询师、敏捷开发技术教练,前IBM区块链研究小组成员、多年架构设计工作经验,《区块链核心技术与应用》作者之一,
现有成熟团队提供区块链开发相关业务(公链,交易所,钱包,Dapp,智能合约)。
工作微信&QQ:360369487,交易所开发与区块链钱包开发业务,加我注明:博客园+开发,想学习golang和rust的同学,也可以加我微信,备注:博客园+golang或博客园+rust,谢谢!
原文:https://www.cnblogs.com/gyc567/p/11910013.html
有疑问加站长微信联系(非本文作者)