<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Rust on sysarcher/@ich_code</title><link>https://sysarcher.github.io/categories/rust/</link><description>Recent content in Rust on sysarcher/@ich_code</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Wed, 15 Apr 2020 21:22:37 +0200</lastBuildDate><atom:link href="https://sysarcher.github.io/categories/rust/index.xml" rel="self" type="application/rss+xml"/><item><title>Rust Lifetimes</title><link>https://sysarcher.github.io/posts/lifetimes/</link><pubDate>Wed, 15 Apr 2020 21:22:37 +0200</pubDate><guid>https://sysarcher.github.io/posts/lifetimes/</guid><description>&lt;p&gt;Coming from a background in C/C++ and other programming languages doesn&amp;rsquo;t help with understanding this one fundamental concept in Rust. Here, I&amp;rsquo;ll try to break it down so it becomes a bit more palatable (and a reference to my future self.)&lt;/p&gt;
&lt;p&gt;A simple example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;fn&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; list &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;vec!&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;34&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;72&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;55&lt;/span&gt;]; &lt;span style="color:#75715e"&gt;// list is created
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; first_two &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;list[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&lt;span style="color:#f92672"&gt;..&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;]; &lt;span style="color:#75715e"&gt;// reference is created (first_two)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;println!&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;first two are &lt;/span&gt;&lt;span style="color:#e6db74"&gt;{:?}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;, first_two); &lt;span style="color:#75715e"&gt;// first_two is referred
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;println!&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;list is &lt;/span&gt;&lt;span style="color:#e6db74"&gt;{:?}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;, list); &lt;span style="color:#75715e"&gt;// list is referred
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;println!&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;again, first two: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;{:?}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;, first_two); &lt;span style="color:#75715e"&gt;// first_two is referred
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} &lt;span style="color:#75715e"&gt;// first_two is dropped, then, list is dropped
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A complicated (yet valid) example:&lt;/p&gt;</description><content:encoded><![CDATA[<p>Coming from a background in C/C++ and other programming languages doesn&rsquo;t help with understanding this one fundamental concept in Rust. Here, I&rsquo;ll try to break it down so it becomes a bit more palatable (and a reference to my future self.)</p>
<p>A simple example:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> list <span style="color:#f92672">=</span> <span style="color:#a6e22e">vec!</span>[<span style="color:#ae81ff">100</span>, <span style="color:#ae81ff">34</span>, <span style="color:#ae81ff">72</span>, <span style="color:#ae81ff">55</span>];               <span style="color:#75715e">// list is created
</span></span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> first_two <span style="color:#f92672">=</span> <span style="color:#f92672">&amp;</span>list[<span style="color:#ae81ff">0</span><span style="color:#f92672">..</span><span style="color:#ae81ff">2</span>];                    <span style="color:#75715e">// reference is created (first_two)
</span></span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">println!</span>(<span style="color:#e6db74">&#34;first two are </span><span style="color:#e6db74">{:?}</span><span style="color:#e6db74">&#34;</span>, first_two);      <span style="color:#75715e">// first_two is referred
</span></span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">println!</span>(<span style="color:#e6db74">&#34;list is </span><span style="color:#e6db74">{:?}</span><span style="color:#e6db74">&#34;</span>, list);                 <span style="color:#75715e">// list is referred
</span></span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">println!</span>(<span style="color:#e6db74">&#34;again, first two: </span><span style="color:#e6db74">{:?}</span><span style="color:#e6db74">&#34;</span>, first_two);  <span style="color:#75715e">// first_two is referred
</span></span></span><span style="display:flex;"><span>}                                                   <span style="color:#75715e">// first_two is dropped, then, list is dropped
</span></span></span></code></pre></div><p>A complicated (yet valid) example:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">return_first_two</span>(borrowed_list: <span style="color:#66d9ef">&amp;</span>[<span style="color:#66d9ef">i32</span>]) -&gt; <span style="color:#66d9ef">&amp;</span>[<span style="color:#66d9ef">i32</span>] {      <span style="color:#75715e">// borrowed_list is a reference
</span></span></span><span style="display:flex;"><span>    <span style="color:#f92672">&amp;</span>borrowed_list[<span style="color:#ae81ff">0</span><span style="color:#f92672">..</span><span style="color:#ae81ff">2</span>]
</span></span><span style="display:flex;"><span>}                                                           <span style="color:#75715e">// borrowed_list is not dropped because it references something outside of its scope
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> list <span style="color:#f92672">=</span> <span style="color:#a6e22e">vec!</span>[<span style="color:#ae81ff">100</span>, <span style="color:#ae81ff">34</span>, <span style="color:#ae81ff">72</span>, <span style="color:#ae81ff">55</span>];               <span style="color:#75715e">// list is created
</span></span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> first_two <span style="color:#f92672">=</span> return_first_two(<span style="color:#f92672">&amp;</span>list);        <span style="color:#75715e">// reference is returned (first_two)
</span></span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">println!</span>(<span style="color:#e6db74">&#34;first two are </span><span style="color:#e6db74">{:?}</span><span style="color:#e6db74">&#34;</span>, first_two);      <span style="color:#75715e">// first_two is referred
</span></span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">println!</span>(<span style="color:#e6db74">&#34;list is </span><span style="color:#e6db74">{:?}</span><span style="color:#e6db74">&#34;</span>, list);                 <span style="color:#75715e">// list is referred
</span></span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">println!</span>(<span style="color:#e6db74">&#34;again, first two: </span><span style="color:#e6db74">{:?}</span><span style="color:#e6db74">&#34;</span>, first_two);  <span style="color:#75715e">// first_two is referred
</span></span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>The main takeaways from the above two examples is:</p>
<ul>
<li><em>the lifetime of values should outlive any of it&rsquo;s references</em></li>
<li><em>a reference&rsquo;s lifetime must be completely contained within the lifetime of the value being referenced</em></li>
</ul>
<p>Generic Lifetimes:</p>
<p><em>the following won&rsquo;t compile</em></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">extern</span> <span style="color:#66d9ef">crate</span> rand;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">simulate_game</span>(home: <span style="color:#66d9ef">&amp;</span><span style="color:#66d9ef">str</span>, away: <span style="color:#66d9ef">&amp;</span><span style="color:#66d9ef">str</span>) -&gt; <span style="color:#66d9ef">&amp;</span><span style="color:#66d9ef">str</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> rand::random() {
</span></span><span style="display:flex;"><span>        home
</span></span><span style="display:flex;"><span>    } <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span>        away
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Rust can not know the lifetime of the return value. It knows that return is valid when <em>both</em> references are valid!!</p>
<p>Adding a generic lifetime param:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">extern</span> <span style="color:#66d9ef">crate</span> rand;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">simulate_game</span><span style="color:#f92672">&lt;</span><span style="color:#a6e22e">&#39;a</span><span style="color:#f92672">&gt;</span>(home: <span style="color:#66d9ef">&amp;</span><span style="color:#a6e22e">&#39;a</span> <span style="color:#66d9ef">str</span>, away: <span style="color:#66d9ef">&amp;</span><span style="color:#a6e22e">&#39;a</span> <span style="color:#66d9ef">str</span>) -&gt; <span style="color:#66d9ef">&amp;</span><span style="color:#a6e22e">&#39;a</span> <span style="color:#66d9ef">str</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> rand::random() {
</span></span><span style="display:flex;"><span>        home
</span></span><span style="display:flex;"><span>    } <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span>        away
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>This syntax expresses intent in signature</p>
<p><strong>Lifetime Elision:</strong></p>
<p>Lifetimes are a part of the language but the language can create some common lifetimes so we don&rsquo;t have to specify them all the time in our programs. This is called Lifetime Elision. The three rules of elided lifetimes:</p>
<ul>
<li>Each parameter gets its own lifetime</li>
<li>One lifetime in parameters =&gt; return</li>
<li>Self reference&rsquo;s lifetime =&gt; return</li>
</ul>
]]></content:encoded></item></channel></rss>