Rust初入门 -- 04 Rust语言之所有权Ownership

Rust初入门 之 所有权Ownership

什么是所有权(ownership)?

先看一段代码,先新建一个项目carog new ownership(见前面的01-Hello-World) , 方便排序,我重名成04-ownership
将src/main.rs改成:

1
2
3
4
5
fn main() {
let a = [1, 2, 3];
let b = a;
println!("a = {:?}, b = {:?}",a, b); // 这是正常: a = [1, 2, 3], b = [1, 2, 3]
}

此时运行正常:

1
2
3
4
5
04-ownership git:(master) ✗ cargo run
Compiling ownership v0.1.0 (/Users/jsl6/work/github/jsl6/rust-learn/04-ownership)
Finished dev [unoptimized + debuginfo] target(s) in 0.29s
Running `target/debug/ownership`
a = [1, 2, 3], b = [1, 2, 3]

接着,将src/main.rs改成:
fn main() {
let a = [1, 2, 3];
let b = a;
println!(“a = {:?}, b = {:?}”,a, b); // 这是正常: a = [1, 2, 3], b = [1, 2, 3]

let c = vec![1, 2, 3];
let d = c;

println!("c = {:?}, d = {:?}",c, d);

}

此时运行cargo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
04-ownership git:(master) ✗ cargo run
Compiling ownership v0.1.0 (/Users/jsl6/work/github/jsl6/rust-learn/04-ownership)
error[E0382]: borrow of moved value: `c`
--> src/main.rs:9:35
|
6 | let c = vec![1, 2, 3];
| - move occurs because `c` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
7 | let d = c;
| - value moved here
8 |
9 | println!("c = {:?}, d = {:?}",c, d);
| ^ value borrowed here after move

error: aborting due to previous error

For more information about this error, try `rustc --explain E0382`.
error: could not compile `ownership`.

To learn more, run the command again with --verbose.

此时运行错误,傲娇的编译器女王,告诉我们:value borrowed here after move

在Rust中,对象都只能有一个所有权(Ownership)。好比一本书,你买了,就有它的所有权,你借给别人,所有权就临时借给了别人,或者到了别人手上,就临时拥有所有权。
Rust的设计哲学,就是默认所有的线程操作都是不安全的。若所有的数据,默认是不可变的,那么所有的线程操作都是线程安全的,是可以共享数据的。

回到上面的例子:
let a = vec![1, 2, 3];

let b = a; // a把数据给b. a已经没有数据的所有权,就访问不了数据,编译器就报错了。

那为何第一段代码不报错了呢?

rust中分两种数据类型:

1.9种基本数据类型: 如: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对两种数据类型,有不同的处理方式:复制 和 移动

  1. 对基本类型,Rust会将a的数据复制给b,并将a所有的数据状态,设为”已复制(coped)”状态。
  2. 对非基本类型,Rust会将c的数据移动,赋值给d,将c的数据状态,设为”已移动(moved)”状态。

所以,Rust内部又定义了两种类型:复制类型(Copy type )移动类型( Move type )

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

core::marker::Copy trait

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