Rust Ownership

Rust Ownership

Rules

  1. 所有的value都有一个对应的owner
  2. 在同一时间,只有一个owner
  3. 如果owner离开其所属范围,该value将会失效

Varible Scope

1
2
3
4
5
{                      // s is not valid here, it’s not yet declared
let s = "hello"; // s is valid from this point forward

// do stuff with s
} // this scope is now over, and s is no longer valid
  • 当变量在指定的范围被描述,即成为有效变量(能被访问)
  • 当变量脱离其描述范围,该变量无效(无法被访问)

Memory and Allocation

Rust是没有garbage collector(GC)机制,以go语言为例,
Go采用异步标记方式,然后定时STW(Stop The World,阻塞所有的goroutine(Go green thread)来完成gc)来同步收回被标记回收的内存区域,
Rust利用Owner的机制,当value的Owner脱离其描述范围,Rust会自动为我们调用drop 函数从而实现Memory return。
ps: c++中也有类似的机制Resource Acquisition Is Initialization (RAII)
内存释放管理示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// MIR code
struct Foo (
/*0:*/ i32,
/*1:*/ Box<i32>,
);

fn foo ()
{
let x = Foo {
/*0:*/ 0: 42,
/*1:*/ 1: Box::new(27),
};
// 此处之后,x脱离其描述范围
}

转化为MIR-code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// URL: https://play.rust-lang.org/  , SHOW MIR
// ps: StorageLive/ StorageDead mark the stack slots as alive/dead
fn Foo(_1: i32, _2: std::boxed::Box<i32>) -> Foo {
let mut _0: Foo; // return place in scope 0 at src/lib.rs:1:1: 4:3

bb0: {
(_0.0: i32) = move _1; // bb0[0]: scope 0 at src/lib.rs:1:1: 4:3
(_0.1: std::boxed::Box<i32>) = move _2; // bb0[1]: scope 0 at src/lib.rs:1:1: 4:3
return; // bb0[2]: scope 0 at src/lib.rs:1:1: 4:3
}
}

fn foo() -> () {
let mut _0: (); // return place in scope 0 at src/lib.rs:7:1: 7:1
let _1: Foo; // "x" in scope 0 at src/lib.rs:8:9: 8:10
let mut _2: std::boxed::Box<i32>; // in scope 0 at src/lib.rs:10:19: 10:31
scope 1 {
}

bb0: {
StorageLive(_1); // bb0[0]: scope 0 at src/lib.rs:8:9: 8:10
StorageLive(_2); // bb0[1]: scope 0 at src/lib.rs:10:19: 10:31
_2 = const std::boxed::Box::<i32>::new(const 27i32) -> bb1; // bb0[2]: scope 0 at src/lib.rs:10:19: 10:31
}

bb1: {
(_1.0: i32) = const 42i32; // bb1[0]: scope 0 at src/lib.rs:8:13: 11:6

(_1.1: std::boxed::Box<i32>) = move _2; // bb1[1]: scope 0 at src/lib.rs:8:13: 11:6

StorageDead(_2); // bb1[2]: scope 0 at src/lib.rs:11:5: 11:6, Box<i32> stack 标记
drop(_1) -> bb2; // bb1[3]: scope 0 at src/lib.rs:12:1: 12:2, 调用drop, 释放该对象内存
// std::mem::drop(_) ,
// pub fn drop<T>(_x: T), (Disposes of a value.)
}

bb2: {
StorageDead(_1); // bb2[0]: scope 0 at src/lib.rs:12:1: 12:2, foo stack 标记
return; // bb2[1]: scope 0 at src/lib.rs:12:2: 12:2,
}
}

Other Coming soon…