# 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 ``` ![](https://i.imgur.com/B0bvevd.jpg) 若真的想要 「複製」 一整份 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 中「申請-釋放」的一對一關係。