{"componentChunkName":"component---src-templates-blog-post-js","path":"/2020-10-16--Ref_note.md/2020-10-16--Ref_note/","result":{"data":{"site":{"siteMetadata":{"title":"Howard's Note","disqusShortname":""}},"markdownRemark":{"id":"3eb96aa1-f037-5831-a9e7-fefc6aae43bd","html":"<blockquote>\n<p>此文章記錄學習中的個人理解</p>\n</blockquote>\n<p><a href=\"https://ithelp.ithome.com.tw/articles/10201653\">文章在這</a></p>\n<h2>所有權、出借、移出</h2>\n<p>rust 特別的地方就是有所有權的概念。透過所有權的規則檢查，可以很有效率的管控記憶體的使用；並且可以檢查是否有 <code class=\"language-text\">dangling refernence</code>的風險。</p>\n<p>雖然在寫程式的時候非常麻煩，但是程式run起來以後，可以基本保證不會有 runtime error的情形發生。習慣以後開發會很有效率。</p>\n<p>同時所有權的觀念也可以融入到打程式的思考當中。</p>\n<h2>參照? 指標？</h2>\n<p>在C++中，其實也有 把 Pointer 跟 Reference 的概念分開來。</p>\n<p>如果你跟我一樣，只熟悉 C，不熟悉 C++ 的話：</p>\n<p>指標的概念就是「指向記憶體的某個位置」。因此，rust中參照也可以視為一個指標，但是它是靜態的（const），不能改變指標指向的位置。</p>\n<p>但是，因為rust多了所有權的概念，而且參照的操作方式也跟c的指標不太一樣，而且必須尊守參照規則。</p>\n<p>（例如：在c當中，要操作參照位置的變數一定要透過指標 derefrence（*）；rust的參照則不需要）</p>\n<p>因此，在 rust 看到 函式傳入參照時，必須以 借出（borrow）來思考，不能使用c的指標思考。</p>\n<blockquote>\n<p>C++ 也有參照的概念，跟rust就比較相似，不過C++並沒有 借出的規則要尊守。</p>\n</blockquote>\n<p>出借的規則</p>\n<hr>\n<p>先不提lifetime，出借主要兩個規則：</p>\n<ul>\n<li>在任何情況下，可以同時借出多個inmutable 參照，但是只能借出一個 mutable 參照。</li>\n<li>在任何時間點下，參照都必須是合法的。</li>\n</ul>\n<h2>智慧指標</h2>\n<p>智慧指標是多了一些能力的指標。</p>\n<p>在rust中，如果智慧指標有實作 <code class=\"language-text\">Deref trait</code>，就基本可以把它當成一般參照使用了。</p>\n<p>它其實不是rust的特別概念，在C++ 也有這個概念。</p>\n<h2>Cell / RefCell</h2>\n<p>上面提到，參照的規則，同時只能有一個 <code class=\"language-text\">mutable</code> 參照。如果有多個參照需要修改，可以使用Cell。</p>\n<p>Cell中的型態需要實作 <code class=\"language-text\">Copy trait</code></p>\n<blockquote>\n<p>Cell 跟 Cow 其實只差一點。Cell 是「取用時復製」，Cow是「寫入時復製」。</p>\n</blockquote>\n<p>RefCell 則是可以使用 boroow (reference)的方式取得 內部的值； 它透過RefCell使用rust 的 lifetime機制實作動態檢查。</p>\n<p>它可以動態檢查 borrow 的規則，將borrow的規則延遲到 runtime。</p>\n<p>以下：</p>\n<div class=\"gatsby-highlight\" data-language=\"rust\"><pre class=\"language-rust\"><code class=\"language-rust\"><span class=\"token keyword\">use</span> <span class=\"token namespace\">std<span class=\"token punctuation\">::</span>cell<span class=\"token punctuation\">::</span></span><span class=\"token class-name\">RefCell</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">fn</span> <span class=\"token function-definition function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">let</span> a <span class=\"token operator\">=</span> <span class=\"token class-name\">RefCell</span><span class=\"token punctuation\">::</span><span class=\"token function\">new</span><span class=\"token punctuation\">(</span><span class=\"token number\">5</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">let</span> b <span class=\"token operator\">=</span> a<span class=\"token punctuation\">.</span><span class=\"token function\">borrow_mut</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">let</span> c <span class=\"token operator\">=</span> a<span class=\"token punctuation\">.</span><span class=\"token function\">borrow_mut</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    \n    <span class=\"token macro property\">println!</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"{}\"</span><span class=\"token punctuation\">,</span> c<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>的確將borrow 放到運行時檢查。</p>\n<h2>Rc</h2>\n<p>Rc 是 reference counting （參照技術）的意思。它是一個記憶體管理的技術。主要概念是，當沒有參照時就釋放記憶體。</p>\n<blockquote>\n<p>Rc::clone 是 clone Rc 這個 pointer，不是Rc 內的值。</p>\n</blockquote>\n<hr>\n<p>文章提到的 linked list，使用RefCell 是為了動態檢查 borrow規則；而使用Rc可以讓多個變數可以同時參照同一個位置（這樣就可以實作雙向linked list了）。</p>\n<p><a href=\"https://play.rust-lang.org/?version=stable&#x26;mode=debug&#x26;edition=2018&#x26;gist=1727a323e4d135699f09d000fcccd293\">playground</a></p>","frontmatter":{"title":"rust RefCell、Cell筆記","date":"October 16, 2020","description":null,"tags":["rust","archive"],"template":"post"}}},"pageContext":{"slug":"/2020-10-16--Ref_note.md/2020-10-16--Ref_note/","previous":{"node":{"fields":{"slug":"/2020-05-31-rxjs-src/Rxjs/"},"frontmatter":{"date":"30 May, 2020","title":"rxjs source trace","tags":["achieve","javascript"]}}},"next":{"node":{"fields":{"slug":"/2021-11-13-gatsby-js-note/"},"frontmatter":{"date":"13 November, 2021","title":"Hello, gatsby","tags":["gatsby"]}}}}},"staticQueryHashes":["2841359383","3810545343","916993862"]}