# Basic 05 : Ownership
> 超級重要!!!!!!!!!!!!!!!!!
>
> Ownership 使 Rust 無須 GC! (Garbage Collector, a.k.a 垃圾蒐集器, Java, C# 都有)
## Memory distribution
> 回憶一下**Stack 和 Heap Memory**
>
> **stack memory** 在申請時必須知道需要多大的靜態空間, 知道後申請一塊相應的空間 (push 至系統 stack 中), <font color="#cd5c5c">無需 System Call</font>; 資料在離開 block 之後就會依序 pop 出, 不須用 GC 幫助。
>
> **heap memory** 則是需要在運行時動態分配空間, 向系統的 Heap 申請空間 <font color="#cd5c5c">(System Call)</font>, 並在不需要的時候通知系統回收 <font color="#cd5c5c">(System Call)</font>。特色是配置時間較長, 效率較 stack 低。
>
> 回收操作在高階語言中會有 GC 幫我們在背後解決回收問題, 但像 C/C++ 就要我們自己回收, 一不注意就可能導致記憶體的流失。
此表告訴我們 Rust 物件的型別、對應的記憶體儲存方式,以及固有的 `trait`。
|Variable Type|Store in|Implemented Trait<br>in Rust|
|:---:|:---:|:-:|
|<font color=mediumSeaGreen>Primitive Type</font>|Stack|<font color=dodgerBlue>Copy</font>|
|<font color=#cd5c5c>Derived Objects</font>|Heap|<font color=orange>Drop</font>|
> 此處 <font color=mediumSeaGreen>Primitive Type</font> 就是前面提過的 : `ints`, `floats`, `char`, `bool`, `tuple` (with all <font color=dodgerblue>copyable</font> elements)
> 此處定義... <font color=#cd5c5c>Derived Objects</font> 就是使用到 Heap 空間的物件
> <font color=dodgerBlue>Copy</font> 和 <font color=orange>Drop</font> 這兩個 `trait` 水火不容,一個物件不可能同時在 System Stack 又在 System Heap 中!
其他語言中的 GC 任務便是追蹤向系統申請的記憶體, 並將不使用的空間釋放掉 (方法眾多, 詳見 [Ref](https://zh.wikipedia.org/wiki/%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6_(%E8%A8%88%E7%AE%97%E6%A9%9F%E7%A7%91%E5%AD%B8)))。
Rust 則是在當某變數超出 Scope 時, 就調用 <font color=orange>drop</font> 方法, 立即釋放空間,這點與 C++ 的解構子如出一轍。
## Move : 改變變數與系統 Heap 中資料的映射
以下看似很稀鬆平常的操作...
```Rust=
let a = 1; // push a with value 1 into stack
let b = a; // push b with value 1 (= a) into stack
```
實際上在 Rust 中, 以上操作是有前提的 : a 需擁有 copy trait。
若是 Derived Object 呢? 以下以字串為例...
```Rust=
let char_array = "Meow"; // of type "& str"
let ds_string = String::from("Meow"); // of type "std::string::String"
// which is the data structure : (char) array list
```
前者不可變長度, 在記憶體就是在 stack 中。
後者是貨真價實的動態字元陣列, 可變長, 在記憶體裡是這樣配置的...
`ds_string` in `stack`...
|name|value|
|:---:|:---:|
|ptr|certain `heap` address|
|length|4|
|capacity|4|
`ds_string` in `heap`...
|index|value|
|:---:|:---:|
|0|M|
|1|e|
|2|o|
|3|w|
看看後者的情況, 若今有另一變數使用 `=` 將以上字串指派之, 在 Rust 這便是 <font color=#cd5c5c size=4>Ownership 的 Move 操作, 將字串的所有權傳遞給另一變數, 原本變數將失去此字串的所有權</font>, 因為 Rust 中, <font color=orange size=4>每個值只能一個 Owner</font>, 不多不少 (智能指標與多重引用的部分未來討論)。
```Rust=
let ds_string = String::from("Meow");
let str2 = ds_string;
println!("{}", str2);
println!("{}", ds_string); // error : borrowed of moved value
```

若真的想要 「複製」 一整份 Derived Object, 可以試著調用 clone 方法, 許多 Derived Object 物件都會將其實作。
```Rust=
let str_1 = String::from("demo-str");
let str_2 = str_1.clone(); // deep copy an derived object
println!("{}, {}", str_1, str_2); // demo-str, demo-str
```
如此一來, 對 Derived Objects 而言, 當變數離開 Scope 時, 擁有 Ownership 的變數會調用 <font color=orange>Drop</font> 方法, 無 Ownership 者不用做任何事, 如此保證了 Heap 中「申請-釋放」的一對一關係。