<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[It's Your Code!]]></title><description><![CDATA[Career coder. Distributed systems. Data infrastructure. Systems programming. Machine learning.

Building things people want.]]></description><link>https://sigwait.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1706645705117/Q8xOoI4Rp.webp</url><title>It&apos;s Your Code!</title><link>https://sigwait.com</link></image><generator>RSS for Node</generator><lastBuildDate>Mon, 18 May 2026 02:56:41 GMT</lastBuildDate><atom:link href="https://sigwait.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Rust Patterns for Lifetime Management]]></title><description><![CDATA[Lifetime management is a core fundamental skill in becoming proficient in using Rust.
Following is a set of patterns designed to help the programmer select an appropriate strategy for ownership or borrowing depending on the program.
Reminder: Lifetim...]]></description><link>https://sigwait.com/rust-patterns-for-lifetime-management</link><guid isPermaLink="true">https://sigwait.com/rust-patterns-for-lifetime-management</guid><category><![CDATA[coding]]></category><category><![CDATA[engineering]]></category><category><![CDATA[General Programming]]></category><category><![CDATA[Rust]]></category><category><![CDATA[software]]></category><dc:creator><![CDATA[Peter M Elias]]></dc:creator><pubDate>Tue, 30 Jan 2024 23:11:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1706654502273/t2dc6cO35.webp?auto=format" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Lifetime management is a core fundamental skill in becoming proficient in using Rust.</p>
<p>Following is a set of patterns designed to help the programmer select an appropriate strategy for ownership or borrowing depending on the program.</p>
<p><strong>Reminder: Lifetimes are a core Rust abstraction that addresses the complexities of <a target="_blank" href="https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html">memory management</a> inherent in any computer engineering task. Lifetimes serve as an alternative to automated garbage collection or direct pointer manipulation found in other languages.</strong></p>
<p>We enumerate the following list of five "lifetime patterns" with pointers on when to consider them appropriate.</p>
<h2 id="heading-borrow-everything">Borrow Everything</h2>
<p>Use when:</p>
<ul>
<li><p>performance is critical by default</p>
</li>
<li><p>there is no specific reason why ownership is required</p>
</li>
<li><p>data structures are expensive to copy</p>
</li>
<li><p>only a single stack frame will be accessing an object reference at any given moment</p>
</li>
<li><p>most or all of the objects originate (and are therefore owned) at the root of the stack</p>
</li>
</ul>
<p>Immutable borrowing should likely be your <a target="_blank" href="https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html">default lifetime strategy</a>. The reason is that data access is temporary and read-only for a linear call chain that is not concurrent nor performs mutation. Functions deeper in the stack can produce unrelated outputs without exclusive or permanent input control.</p>
<p>Immutable borrows form a chain of ownership and lending as execution progresses into the stack.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706645949909/qXGNgTOLn.png?auto=format" alt="illustration-1" />
<em>As execution winds the stack, later frames borrow the value owned by the earlier frames. As the stack unwinds, the earlier frame remains the value owner until program termination. The later frames have gone out of scope, dropping their borrowed references.</em></p>
<p>The critical thing to understand here is that the beginning and end states are the same for a borrowed value because borrowing does not transfer ownership away from the originating caller.</p>
<p>Code Example:</p>
<pre><code class="lang-rust"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Config</span></span> {
    path: <span class="hljs-built_in">String</span>
}

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-comment">// [`main`] function owns [`Config`] object at the beginning of the stack.</span>
    <span class="hljs-keyword">let</span> config = Config {
        path: <span class="hljs-built_in">String</span>::from(<span class="hljs-string">"/etc/nginx/nginx.conf"</span>)
    };

    <span class="hljs-comment">// [`is_valid_config`] is now borrowing [`&amp;Config`] by reference</span>
    <span class="hljs-keyword">match</span> is_valid_config(&amp;config) {
        <span class="hljs-literal">true</span> =&gt; <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Valid config"</span>),
        <span class="hljs-literal">false</span> =&gt; <span class="hljs-built_in">println!</span>(<span class="hljs-string">"Invalid config"</span>)
    }

    <span class="hljs-comment">// [`main`] function still owns [`Config`] at the end of execution</span>
}

<span class="hljs-comment">/// Checking to see if [`Config.path`] is/not empty does not</span>
<span class="hljs-comment">/// require a dedicated copy or exclusive control of the value.</span>
<span class="hljs-comment">/// Borrowing is the best choice here.</span>
<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">is_valid_config</span></span>(config: &amp;Config) -&gt; <span class="hljs-built_in">bool</span> {
    !config.path.is_empty()
}
</code></pre>
<p>As the comments indicate, this works because the function later in the stack requires neither exclusive control nor a dedicated copy to perform its work on the config object.</p>
<p>If the callee requires neither of those properties nor intends to consume the value (destroy it), then the best solution is likely the immutable shared reference (aka the borrow).</p>
<p>We do not go into mutable borrowing in this guide because the strategies for mutation require additional considerations, such as the use of <a target="_blank" href="https://doc.rust-lang.org/book/ch16-03-shared-state.html?search=#using-mutexes-to-allow-access-to-data-from-one-thread-at-a-time">Mutex</a>. We will cover these in an upcoming guide.</p>
<h2 id="heading-borrow-most-things-clone-some-things">Borrow Most Things, Clone Some Things</h2>
<p>Use when:</p>
<ul>
<li><p>most objects require only temporary access</p>
</li>
<li><p>a subset of objects will be permanently consumed or altered</p>
</li>
<li><p>a subset of objects originate later in the stack but are returned for ownership nearer to the stack root</p>
</li>
<li><p>the overhead of <code>Clone</code>’ing is deemed acceptable</p>
</li>
</ul>
<p>A slight variation on Pattern #1, this is where the invariants of immutable borrowing are satisfied with the exception that a callee must <a target="_blank" href="https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html#variables-and-data-interacting-with-clone">operate on its copy</a> of a value that must also <strong>remain owned</strong> by a caller earlier in the stack.</p>
<p>The essential constraint here is that we can neither move nor borrow the object. Two parts of the program require separate copies of the same object for valid reasons.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706646090540/LFnb1EmsL.png?auto=format" alt="illustration-2" />
<em>X is Clone’d while Y is &amp;borrowed. Frame #9 can do whatever it wants with its copy of X (including destroying it). However, at the end of execution, Frame #0 still owns the original copy of X and the original reference to Y it was lending out.</em></p>
<p>Note that, again, the start and end states are the same. Even though Frame #9 has its copy of X to use as needed, Frame #0 still retains ownership of the original copy. Cloning makes sense when X is cheap to copy, and Frame #9 is doing something that requires exclusive control of the value.</p>
<p>Let’s modify our prior example to see a situation where that could be necessary:</p>
<pre><code class="lang-rust"><span class="hljs-meta">#[derive(Clone)]</span>
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Config</span></span> {
    path: <span class="hljs-built_in">String</span>,
}

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Versioned</span></span>&lt;O&gt; {
    version: <span class="hljs-built_in">u32</span>,
    obj: O,
}

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-comment">// `main` function owns the `Config` object at the beginning of the stack.</span>
    <span class="hljs-keyword">let</span> config = Config {
        path: <span class="hljs-built_in">String</span>::from(<span class="hljs-string">"/etc/nginx/nginx.conf"</span>),
    };

    <span class="hljs-comment">/*
      `config` is `Clone`'d to provide `save_config_version` with
      a copy of `config` so that it can save it into its `Versioned`
      construct. Copying the value is necessary because we must preserve
      the version even if the original copy is changed later.
      Therefore, we store a copy of it within the version struct.
    */</span>
    <span class="hljs-keyword">let</span> version_1 = save_config_version(config.clone());

    <span class="hljs-comment">// `main` function still owns `config` at the end of execution</span>

    <span class="hljs-comment">// `save_config_version` owned the copy of `Config` while it was</span>
    <span class="hljs-comment">// creating its owned `Versioned` object. Then it dropped</span>
    <span class="hljs-comment">// its ownership of `config` and `Versioned` by returning them both</span>
    <span class="hljs-comment">// to `main`, bound as `version_1`.</span>

    <span class="hljs-built_in">assert_eq!</span>(version_1.version, <span class="hljs-number">1</span>);
    <span class="hljs-built_in">assert_eq!</span>(version_1.obj.path, <span class="hljs-string">"/etc/nginx/nginx.conf"</span>);
}

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">save_config_version</span></span>(config: Config) -&gt; Versioned&lt;Config&gt; {
    Versioned {
        version: <span class="hljs-number">1</span>,
        obj: config,
    }
}
</code></pre>
<p><em>Note: the use of the <code>#[derive(Clone)]</code> trait macro to ensure that <code>Config</code> is Cloneable.</em></p>
<p>The main reasons Clone’ing is an appropriate strategy here are because:</p>
<ul>
<li>The value is cheap to copy (a small struct of primitives)</li>
<li>The program's intended goal is to ensure that the copies of the value can be independently modified (or preserved).</li>
</ul>
<p>Therefore, we must have multiple copies of the data structure to treat independently.</p>
<p>We could not do this with mutable borrowing or reference counting because all references would see any mutation. We cannot move the value because we will lose its original state after it is mutated.</p>
<h2 id="heading-borrow-most-things-move-some-things">Borrow Most Things, Move Some Things</h2>
<p>Use when:</p>
<ul>
<li><p>most objects require only temporary access</p>
</li>
<li><p>we need to consume or alter a subset of objects permanently</p>
</li>
<li><p>a subset of objects are expensive to <code>Clone</code></p>
</li>
<li><p>a subset of objects are only required by a single function or subprocess</p>
</li>
</ul>
<p>Similar to the prior scenario where the callee requires ownership of the value, but for some reason, <code>Clone</code> is not an option.</p>
<p>There are valid reasons to require ownership. The most obvious is if <code>Clone</code> would be too expensive because the value has a large memory footprint.</p>
<p>In this case, you may still be borrowing most things, but you specifically identify the object that <a target="_blank" href="https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html#variables-and-data-interacting-with-move">needs to move and pass it by value</a> to the callee such that ownership transfers away from the caller and into the callee.</p>
<p>From there, either:</p>
<ol>
<li>The callee eventually passes ownership back to the caller either as the same value or a derivative value</li>
<li>The callee drops the object after it goes out of scope, and it is never seen nor heard from again</li>
</ol>
<p>In either case, the caller may not reference the object after moving it to the callee. If the callee returns ownership to the caller, the caller may reference the returned value as a new binding. The original binding is no longer valid after a move.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706646107663/wh1G4izwC.png?auto=format" alt="illustration-3" />
<em>Notably, at the end of the program, Frame #0 is left still owning Y but no longer owns X because X was moved to Frame #9 and never returned as a new binding. Frame #0 will never know what happened to X :(</em></p>
<p>We adapt our example again to see a situation where this might occur:</p>
<pre><code class="lang-rust"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Config</span></span> {
    path: <span class="hljs-built_in">String</span>,
    very_long_vector: <span class="hljs-built_in">Vec</span>&lt;<span class="hljs-built_in">String</span>&gt;,
}

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Versioned</span></span>&lt;O&gt; {
    version: <span class="hljs-built_in">u32</span>,
    obj: O,
}

<span class="hljs-keyword">const</span> CAPACITY: <span class="hljs-built_in">usize</span> = <span class="hljs-built_in">usize</span>::MAX / <span class="hljs-number">10000000</span>;

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-comment">// `main` function owns the `Config` object at the beginning of the stack.</span>
    <span class="hljs-keyword">let</span> config = Config {
        path: <span class="hljs-built_in">String</span>::from(<span class="hljs-string">"/etc/nginx/nginx.conf"</span>),
        very_long_vector: <span class="hljs-built_in">Vec</span>::with_capacity(CAPACITY),
    };

    <span class="hljs-comment">// `config` binding moves into `save_config_version` and</span>
    <span class="hljs-comment">// dropped from this scope. The new `Versioned` representation of</span>
    <span class="hljs-comment">// `config` is returned and stored in the new binding called</span>
    <span class="hljs-comment">// `versioned_config`.</span>
    <span class="hljs-keyword">let</span> versioned_config = save_config_version(config);

    <span class="hljs-comment">// `config` is no longer a valid binding at this point</span>

    <span class="hljs-built_in">assert_eq!</span>(versioned_config.version, <span class="hljs-number">1</span>);
    <span class="hljs-built_in">assert_eq!</span>(versioned_config.obj.path, <span class="hljs-string">"/etc/nginx/nginx.conf"</span>);
    <span class="hljs-built_in">assert_eq!</span>(versioned_config.obj.very_long_vector.capacity(), CAPACITY);
}

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">save_config_version</span></span>(config: Config) -&gt; Versioned&lt;Config&gt; {
    Versioned {
        version: <span class="hljs-number">1</span>,
        obj: config,
    }
}
</code></pre>
<p>This example shows a situation where the <code>Config</code> object is now too expensive to Clone due to the huge data structure (giant vector) it contains.</p>
<p>Therefore, when we decide to make a versioned representation of it, we allow the versioning function to take exclusive ownership of the value (consume it) and take ownership of the new value returned in its place.</p>
<p>The <code>save_config_version</code> function performs its work without the expense of having an owned copy of the data structure.</p>
<p>If we wanted to make a second version of this <code>Config</code>, we would face this problem again. The solution to that problem is more sophisticated and beyond the scope of this guide.</p>
<h2 id="heading-move-all-the-things">Move All the Things</h2>
<p>Use when:</p>
<ul>
<li><p>objects are expensive to Clone</p>
</li>
<li><p>the inner scope may outlive the outer scope</p>
</li>
</ul>
<p>Moving is necessary when <code>Clone</code> is too expensive or the scope needing the value may outlive the scope providing the value.</p>
<p>One example is a program with two tasks. One task reads data from a socket, and the other performs a longer-running computation on the data.</p>
<p>The task reading data from the socket could pass references to the task processing the data, but there is a problem. If the task processing the data takes longer to complete than the task reading data from the buffer, the processing task will outlive the buffer reading task.</p>
<p>If the buffer-reading task goes out of scope before the processing task, the processing task is now holding a reference to nothing. Rust does not allow this. The borrow checker will detect this possibility and report an error.</p>
<p>In this situation, you have to move the value from the task that reads the data to the task that processes the data. Often this is expressed as a closure created with the <code>move { }</code> or <code>async move { }</code> blocks.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706646120906/9I2UroF2x.png?auto=format" alt="illustration-4" />
<em>Here, we see a major difference: ownership is transferred from Task #0 to Task #1, but at the end of execution, Task #0 no longer exists. Task #1 has outlived Task #0 and retains sole ownership of X. Task #1 cannot borrow X from Task #0 because Task #0 may terminate before Task #1. The borrow-checker will not allow this.</em></p>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> reqwest::Client;

<span class="hljs-keyword">const</span> URL: &amp;<span class="hljs-built_in">str</span> = <span class="hljs-string">"https://google.com"</span>;

<span class="hljs-meta">#[tokio::main]</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-keyword">let</span> client = Client::new();

    tokio::spawn(<span class="hljs-keyword">async</span> <span class="hljs-keyword">move</span> { client.get(URL).send().<span class="hljs-keyword">await</span>.unwrap() })
        .<span class="hljs-keyword">await</span>
        .unwrap();

    <span class="hljs-comment">// `client` is no longer a valid reference at this point</span>
    <span class="hljs-comment">// It permanently moves into the `spawn`'d closure</span>
}
</code></pre>
<p>Here, we see that the outer scope <code>main</code> representing Task #0 will create a <code>client</code> and move it to be owned by Task #1. Since Task #1 is async and <code>main</code> does not block, the <code>main</code> scope will be dropped immediately after starting Task #1.</p>
<p>Task #1 can continue to run until completion as it has taken ownership of the <code>client</code> needed to perform its work.</p>
<h2 id="heading-reference-count-certain-things">Reference Count Certain Things</h2>
<p>Use when:</p>
<ul>
<li><p>objects are expensive to clone</p>
</li>
<li><p>multiple threads or processes must access the same references concurrently</p>
</li>
<li><p>moving and returning ownership is prohibitively complex or precluded by concurrent access requirements</p>
</li>
<li><p>you are already using locks (<a target="_blank" href="https://doc.rust-lang.org/book/ch16-03-shared-state.html?search=#using-mutexes-to-allow-access-to-data-from-one-thread-at-a-time">Mutex</a>) for atomic mutation</p>
</li>
</ul>
<p>Reference counting is the most complex technique, where we want to neither move nor implicitly borrow. One can think of this approach as a more explicit form of borrowing where we are <a target="_blank" href="https://doc.rust-lang.org/book/ch15-04-rc.html#using-rct-to-share-data">tracking each reference</a> holder to an object explicitly using a counter that tracks new and dropped references.</p>
<p>We get the efficiency of borrowing with the semantics of ownership as long as we do not mutate the underlying value.</p>
<p>Rust's two primary reference counted types are <code>Rc&lt;T&gt;</code> and <code>Arc&lt;T&gt;</code>. Rc means <a target="_blank" href="https://doc.rust-lang.org/std/rc/struct.Rc.html">"reference counted"</a> and Arc means <a target="_blank" href="https://doc.rust-lang.org/std/sync/struct.Arc.html">"atomically reference counted"</a>. Calling <code>.clone()</code> on an <code>Rc&lt;T&gt;</code> or <code>Arc&lt;T&gt;</code> does not physically copy the inner value but instead creates a smart pointer to the heap-allocated inner value.</p>
<p>From the perspective of the borrow-checker, the receiver of a <code>Clone</code>’d reference counted type has an “owned” copy of the value because the lifetime of the inner value has been moved outside the stack and onto the heap. The value will remain on the heap until the last reference drops, ensuring that even if earlier references drop, later references will still be valid for as long as needed.</p>
<p>Reference counted type <code>Clone</code>s are still shared references — the same way a borrow is — but allow the semantics of an owned value without the overhead of copying the value.</p>
<p>It may seem like this should always be the best option — but in practice, the extra boilerplate and complexity are only worth it if the more basic lifetime strategies prove insufficient.</p>
<p>Reserve this approach for when the lifetimes of your stack frames (scopes) are non-linear and moving or cloning bits are not appropriate for control flow or performance reasons.</p>
<p>Note: reference counting is not <a target="_blank" href="https://doc.rust-lang.org/book/ch15-06-reference-cycles.html?highlight=Weak">without pitfalls if done improperly</a>.</p>
<p>Let’s look at when using a reference counted type would be an appropriate solution.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706646132005/bLIbFMURw.png?auto=format" alt="illustration-5" />
<em>Here, we see that <code>Arc::new(X)</code> moves the value from the stack to the heap. Then, when <code>clone()</code> is called on the value by subsequent frames, they receive a pointer to the heap location of X, and the reference counter goes up or down as references are taken or dropped.</em></p>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> std::iter;
<span class="hljs-keyword">use</span> std::sync::Arc;

<span class="hljs-meta">#[derive(Clone, Debug, PartialEq)]</span>
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Config</span></span> {
    very_large_vec: <span class="hljs-built_in">Vec</span>&lt;<span class="hljs-built_in">String</span>&gt;,
}

<span class="hljs-meta">#[derive(Clone)]</span>
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Worker</span></span> {
    config: Arc&lt;Config&gt;,
}

<span class="hljs-keyword">const</span> CAPACITY: <span class="hljs-built_in">usize</span> = <span class="hljs-built_in">usize</span>::MAX / <span class="hljs-number">10000000</span>;

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-comment">// Our `config` object is very large and too expensive to copy.</span>
    <span class="hljs-keyword">let</span> config = Config {
        very_large_vec: <span class="hljs-built_in">Vec</span>::with_capacity(CAPACITY),
    };

    <span class="hljs-comment">// We move `config` into the `Arc::new` constructor, which consumes</span>
    <span class="hljs-comment">// the original `config` value and returns it wrapped in the</span>
    <span class="hljs-comment">// `Arc&lt;T&gt;` struct.</span>
    <span class="hljs-comment">// We bind the new Arc&lt;T&gt; wrapped value to a binding of the</span>
    <span class="hljs-comment">// same name (`config`) as the previous binding is no longer valid.</span>
    <span class="hljs-keyword">let</span> config = Arc::new(config);

    <span class="hljs-comment">// Here, we use `iter` functions to generate a `Vec` of 100 `Worker`</span>
    <span class="hljs-comment">// structs.</span>
    <span class="hljs-comment">// It would be too expensive to Clone `config` 100 times.</span>
    <span class="hljs-comment">// Thanks to the use of `Arc&lt;Config&gt;`, we are only storing 1 copy</span>
    <span class="hljs-comment">// of `Config` on the heap and passing a counted reference to each</span>
    <span class="hljs-comment">// `Worker` by calling `clone()` on the `Arc&lt;Config&gt;` object.</span>
    <span class="hljs-keyword">let</span> workers: <span class="hljs-built_in">Vec</span>&lt;Worker&gt; = iter::repeat(Worker {
        config: config.clone(),
    })
    .take(<span class="hljs-number">100</span>)
    .collect();

    <span class="hljs-built_in">assert_eq!</span>(workers[<span class="hljs-number">0</span>].config.very_large_vec.capacity(), CAPACITY);
    <span class="hljs-built_in">assert_eq!</span>(workers[<span class="hljs-number">0</span>].config, workers[<span class="hljs-number">1</span>].config);
}
</code></pre>
<p>We will not cover the mutation case here as that will require introducing <a target="_blank" href="https://doc.rust-lang.org/book/ch16-03-shared-state.html?search=#using-mutexes-to-allow-access-to-data-from-one-thread-at-a-time">Mutex</a>. Stay tuned for more in an upcoming article.</p>
<p><strong>Wrapping Up</strong></p>
<p>This guide provides a practical framework for planning your lifetime management approach when designing programs in Rust.</p>
<p><strong>Remember: defaulting to immutable borrowing is usually a good starting point.</strong></p>
<p>Values that will be <strong>destroyed</strong>, <strong>returned</strong>, or <strong>irreversibly</strong> transformed are probably good candidates for <strong>moving</strong> or <strong>cloning</strong>.</p>
<p>Values that will be used exclusively by a scope that outlives their original scope must be moved into the longer-living scope so they can exist after the original scope drops.</p>
<p>If performance constraints are bound and concurrent ownership or mutation is required, reference counting is probably the way to go.</p>
<p>A note on lifetime annotations: this guide does not cover <a target="_blank" href="https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html">lifetime annotations</a> (<code>&lt;‘a&gt;</code>) because they do not provide actual control over the lifetimes of references at runtime. They are hints to the Rust compiler (borrow checker) to disambiguate type signatures where the compiler cannot easily infer the programmer's intention for which references do and do not share lifetimes.</p>
<p>We will do a separate piece on lifetime annotations and when they are necessary and useful.</p>
<p><strong>Follow + Subscribe for More!</strong></p>


<ul>
<li><a target="_blank" href="https://twitter.com/itsyourcode?ref_src=twsrc%5Etfw" class="twitter-follow-button">Follow @itsyourcode</a></li>
<li><a target="_blank" class="github-button" href="https://github.com/txbm">Follow @txbm</a></li>
<li><a target="_blank" class="github-button" href="https://github.com/sponsors/txbm">Sponsor</a></li>
</ul>
<p><strong>Additional Reading</strong></p>
<ul>
<li><a target="_blank" href="https://richardanaya.medium.com/a-journey-through-rust-lifetimes-5a08782c7091">A Journey Through Rust Lifetimes</a></li>
<li><a target="_blank" href="https://academy.patika.dev/courses/rust-programming/advanced-lifetimes">Advanced Lifetimes</a></li>
<li><a target="_blank" href="https://www.lurklurk.org/effective-rust/lifetimes.html">Understand Lifetimes</a></li>
<li><a target="_blank" href="https://doc.rust-lang.org/nomicon/lifetimes.html">Rust Doc: Lifetimes</a></li>
<li><a target="_blank" href="https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/lifetimes.html">Rust Book 1st Edition: Lifetimes</a></li>
<li><a target="_blank" href="https://earthly.dev/blog/rust-lifetimes-ownership-burrowing/">A Complete Guide to Ownership and Borrowing</a></li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=gRAVZv7V91Q&amp;t=5s">but what is 'a lifetime</a></li>
</ul>
]]></content:encoded></item></channel></rss>