學 Rust 要有大局觀 -二- Rust 的精髓

 Rust 的精髓

上一篇 (學 Rust 要有大局觀) 我們從 rust 的安裝部署,到 cargo 的基本使用,給大家做了科普,爲了保證可以降低 Rust 的學習難度,一開始我們必須掃除掉除了基本語法之外的核心難點,這一篇我們關注於所有權(+ 生命週期) 這個 Rust 最難學的部分, 但是梁小孩今天十分鐘之內爭取讓你有學習 Rust 的戰略思維,知道 rust 應該怎麼學~

Rust 精髓

我嘗試用幾個簡單的詞彙說明 Rust 的設計精髓和底層原理,方便對比其他語言和 Rust 的不同之處

•Rust 變量具有閱後即焚的特性, 相比之下其他語言的變量都是耐用品, 而 Rust 的變量屬於一次性用品•Rust 語言中變量使用值擁有是明確區分的,而且其他語言的變量等號基本都是賦值,但是 Rust 是所有權讓渡

三種常見的內存模式

從下面三行簡單的賦值語句, 我們直觀感受一下 c++,python, 還有 Rust 的不同處理方式

# c++代碼,僅僅用來說明簡單邏輯
auto s = std::vector<std::string>{ "udon", "ramen", "soba" }; 
auto t = s;    // 第一次使用s
auto u = s;    // 第二次使用s

c++ will copy

c++-copy

棧內的變量一直增長 (從左往右),變量也一直可以被訪問使用. 而且棧到堆的指向關係互相交織(網狀); 由於 C++ 默認採用 copy 的方式進行operator=的操作,即使是std::vector複雜的 STL 結構,都是直接複製, 鑑於這種默認動作開銷比較大,一般程序員會手工引入引用或者指針來優化 (問題隨之而來,棧到堆的指針遲早變成網)

Python will count

python3-count

對於 python 而言,由於有 gc 的存在,gc 採用了reference count技術,所以邏輯層次上多了一個 PyObject 的中間層,保存了計數信息, 由於採用的是計數機制,而 python 棧上的變量都是對同一個值的多個引用,修改其中一個總是會讓其他變量的值也都一起變化

Rust will move (and crush!!)

rust-will-move-and-crush

對於 Rust 而言,變量的賦值操作等同於值擁有權的讓渡, 它的意義就是auto t = s;這種語句一旦執行,相當於棧變量t取代了棧變量s,擁有了底層的值, 隨之而來的就是s在編譯階段就被編譯器標識爲不再可用; 這是 rust 編譯器處理代碼的邏輯,所以auto u = s;這樣的語句根本不會通過編譯,更無需再考慮代碼執行; x 這一切都發生在代碼分析階段,編譯過程中, 不管是簡單的賦值,還是被函數形參,還是一個值被從函數返回: 都是直接的管理權讓渡

思考題

一個 for 循環,內部一個 print 函數打印了上面列表,這樣一個簡單的邏輯不同的語言會出現什麼樣的內存結果?

•c++ OK, s 可以再次被賦值使用,打印,進行各種操作 •Python OK, s 也可以正常使用 •Rust OK, 可以正常打印,但是 for 訓話結束之後,所有字符串堆中的資源都被釋放了, s 變成了不可再用的變量

好了,是不是感覺太神奇了~~, Rust 對變量的使用就是直接拿來,如果沒有新的上下文接受讓渡, 變量就被直接銷燬了, 這個神奇的設定就是 Rust 有別於其他各種語言,並且會有move sematicborrowlifetime的最底層設定, 這就是 rust 的遊戲規則.

簡單發散思考, 這個神奇的move sematic設定會導致什麼樣的直觀現象呢,類似與 c++,java,python 各種語言其實隨着程序一點一點執行,可能會有成百上千的 object 產生,其中的變量指針,引用,copy 互相交織在一起,看起來就會亂糟糟的,這常被稱之爲對象之海(如下圖)

a sea of objects

由於 rust 特立獨行的底層遊戲規則,不管程序運行了多久,邏輯上看來,不管對象內部有多少子元素,列表還是字典,永遠只有一個 root(擁有它), 再加上我們將要說到的使用權的限制,Rust 的堆棧變量總是非常乾淨清楚 (給你了,你就是owner), 你不會有類似 c++ 中三方庫函數返回了一個指針, 我應該free?的疑問.(如下圖)

rust object tree

本文簡答說明了 Rust 最核心的底層設計,關於所有權的相關內容,我們可以詳細展開了, 敬請期待

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/VJG4yV1x88BNXTijbIe4UQ