<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ownership on</title><link>/tags/ownership/</link><description>Recent content in Ownership on</description><generator>Hugo</generator><language>en</language><lastBuildDate>Tue, 18 Jun 2024 12:38:00 +0000</lastBuildDate><atom:link href="/tags/ownership/index.xml" rel="self" type="application/rss+xml"/><item><title>Lesson 15: When You're Fighting the Borrow Checker — Restructure, Don't Hack</title><link>/post/rust/rust-own-fighting-borrow-checker/</link><pubDate>Tue, 18 Jun 2024 12:38:00 +0000</pubDate><guid>/post/rust/rust-own-fighting-borrow-checker/</guid><description>&lt;p&gt;Every Rust developer has been there. You&amp;rsquo;re implementing something that feels simple. It works in your head. But the borrow checker says no. You try different approaches. More errors. You start adding &lt;code&gt;.clone()&lt;/code&gt; everywhere. You wrap things in &lt;code&gt;Rc&amp;lt;RefCell&amp;lt;...&amp;gt;&amp;gt;&lt;/code&gt;. You consider &lt;code&gt;unsafe&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Stop. Take a breath. The borrow checker isn&amp;rsquo;t wrong — your data flow is confused. And there&amp;rsquo;s almost always a clean restructuring that makes the error disappear.&lt;/p&gt;
&lt;p&gt;This lesson is a field guide. Real patterns that fight the borrow checker, and the restructurings that fix them.&lt;/p&gt;</description></item><item><title>Lesson 14: Pin and Unpin — Why Async Needs Them</title><link>/post/rust/rust-own-pin-unpin/</link><pubDate>Fri, 14 Jun 2024 20:05:00 +0000</pubDate><guid>/post/rust/rust-own-pin-unpin/</guid><description>&lt;p&gt;&lt;code&gt;Pin&lt;/code&gt; is the concept that makes experienced Rust developers pause. Not because it&amp;rsquo;s inherently complex — it&amp;rsquo;s actually a pretty small API — but because understanding &lt;em&gt;why&lt;/em&gt; it exists requires connecting several ideas: self-referential structs, async/await desugaring, and move semantics.&lt;/p&gt;
&lt;p&gt;I struggled with Pin for months. Then I understood what async does under the hood, and Pin suddenly made perfect sense. So that&amp;rsquo;s how I&amp;rsquo;m going to explain it.&lt;/p&gt;
&lt;h2 id="the-setup-what-async-really-does"&gt;The Setup: What Async Really Does&lt;/h2&gt;
&lt;p&gt;When you write an async function:&lt;/p&gt;</description></item><item><title>Lesson 13: Weak References — Breaking Cycles</title><link>/post/rust/rust-own-weak-references/</link><pubDate>Mon, 10 Jun 2024 09:15:00 +0000</pubDate><guid>/post/rust/rust-own-weak-references/</guid><description>&lt;p&gt;Reference counting has a fatal flaw: cycles. If A owns B and B owns A, neither reference count hits zero. The memory is leaked — not freed when it should be, not freed ever. In a garbage-collected language, the GC would detect this cycle and clean it up. Rust&amp;rsquo;s &lt;code&gt;Rc&lt;/code&gt;/&lt;code&gt;Arc&lt;/code&gt; can&amp;rsquo;t do that.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Weak&lt;/code&gt; references are the solution. And honestly, if you understand why they exist, you understand half of what makes garbage collectors complex.&lt;/p&gt;</description></item><item><title>Lesson 12: Rc and Arc — Shared Ownership</title><link>/post/rust/rust-own-rc-arc/</link><pubDate>Fri, 07 Jun 2024 17:50:00 +0000</pubDate><guid>/post/rust/rust-own-rc-arc/</guid><description>&lt;p&gt;Rust&amp;rsquo;s ownership model says every value has one owner. But what happens when multiple parts of your program genuinely need to own the same data? Trees with shared nodes. Graphs with cycles. Observer patterns. Caches shared between subsystems.&lt;/p&gt;
&lt;p&gt;Single ownership doesn&amp;rsquo;t fit everything. &lt;code&gt;Rc&lt;/code&gt; and &lt;code&gt;Arc&lt;/code&gt; are Rust&amp;rsquo;s answer — reference-counted smart pointers that enable shared ownership with deterministic cleanup.&lt;/p&gt;
&lt;h2 id="the-problem-multiple-owners"&gt;The Problem: Multiple Owners&lt;/h2&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:#75715e"&gt;// This doesn&amp;#39;t work — who owns the shared config?
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ServiceA&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; config: &lt;span style="color:#a6e22e"&gt;AppConfig&lt;/span&gt;, &lt;span style="color:#75715e"&gt;// owns it
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ServiceB&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; config: &lt;span style="color:#a6e22e"&gt;AppConfig&lt;/span&gt;, &lt;span style="color:#75715e"&gt;// also owns a copy? expensive clone
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You could pass references, but then you&amp;rsquo;re dealing with lifetimes everywhere. And if the config needs to outlive any individual service, you need &lt;code&gt;'static&lt;/code&gt; or owned data.&lt;/p&gt;</description></item><item><title>Lesson 11: Interior Mutability — Cell, RefCell, and the Rules</title><link>/post/rust/rust-own-interior-mutability/</link><pubDate>Tue, 04 Jun 2024 11:30:00 +0000</pubDate><guid>/post/rust/rust-own-interior-mutability/</guid><description>&lt;p&gt;Rust&amp;rsquo;s borrowing rules say you can&amp;rsquo;t mutate through a shared reference. Period. Except — sometimes you need to. Caching, reference counting, lazy initialization, mock objects in tests. Legitimate use cases where the &amp;ldquo;no mutation through &lt;code&gt;&amp;amp;T&lt;/code&gt;&amp;rdquo; rule is too restrictive.&lt;/p&gt;
&lt;p&gt;Interior mutability is the escape hatch. It moves the borrow check from compile time to runtime. And yes, it can panic if you get it wrong. That&amp;rsquo;s the tradeoff.&lt;/p&gt;
&lt;h2 id="the-problem-mutation-through-self"&gt;The Problem: Mutation Through &amp;amp;self&lt;/h2&gt;
&lt;p&gt;You&amp;rsquo;re building a struct with a method that logically doesn&amp;rsquo;t modify the struct&amp;rsquo;s public state but needs to update some internal bookkeeping:&lt;/p&gt;</description></item><item><title>Lesson 10: Self-Referential Structs — The Problem and Solutions</title><link>/post/rust/rust-own-self-referential/</link><pubDate>Sun, 02 Jun 2024 15:40:00 +0000</pubDate><guid>/post/rust/rust-own-self-referential/</guid><description>&lt;p&gt;Every Rust developer eventually tries to build this: a struct that owns some data AND holds a reference into that data. It seems perfectly reasonable. It&amp;rsquo;s also the single thing Rust refuses to let you do safely — and for very good reasons.&lt;/p&gt;
&lt;p&gt;I wasted two days on this in my second month of Rust. Let me save you those two days.&lt;/p&gt;
&lt;h2 id="the-desire"&gt;The Desire&lt;/h2&gt;
&lt;p&gt;You want a struct like this:&lt;/p&gt;</description></item><item><title>Lesson 9: Higher-Ranked Trait Bounds — for&lt;'a&gt; Explained</title><link>/post/rust/rust-own-higher-ranked/</link><pubDate>Fri, 31 May 2024 21:15:00 +0000</pubDate><guid>/post/rust/rust-own-higher-ranked/</guid><description>&lt;p&gt;If regular lifetime annotations are Rust&amp;rsquo;s intermediate boss, &lt;code&gt;for&amp;lt;'a&amp;gt;&lt;/code&gt; is the final boss. Higher-Ranked Trait Bounds (HRTBs) look terrifying in signatures, but they solve a very specific and real problem.&lt;/p&gt;
&lt;p&gt;I avoided understanding HRTBs for over a year. Then I tried to write a function that takes a closure accepting references with &lt;em&gt;any&lt;/em&gt; lifetime, and suddenly I had no choice. Let me save you that year.&lt;/p&gt;
&lt;h2 id="the-problem"&gt;The Problem&lt;/h2&gt;
&lt;p&gt;Say you want a function that accepts a closure. The closure takes a &lt;code&gt;&amp;amp;str&lt;/code&gt; and returns something:&lt;/p&gt;</description></item><item><title>Lesson 8: 'static — Not What You Think</title><link>/post/rust/rust-own-static-lifetime/</link><pubDate>Wed, 29 May 2024 13:25:00 +0000</pubDate><guid>/post/rust/rust-own-static-lifetime/</guid><description>&lt;p&gt;&lt;code&gt;'static&lt;/code&gt; is the most misunderstood lifetime in Rust. Most people think it means &amp;ldquo;lives forever&amp;rdquo; or &amp;ldquo;global variable.&amp;rdquo; It kind of does — but also doesn&amp;rsquo;t. And the way it interacts with trait bounds will surprise you.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve seen experienced Rust developers get this wrong. So don&amp;rsquo;t feel bad if it&amp;rsquo;s been confusing.&lt;/p&gt;
&lt;h2 id="what-static-actually-means"&gt;What &amp;lsquo;static Actually Means&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;'static&lt;/code&gt; means: &amp;ldquo;this reference is valid for the entire duration of the program.&amp;rdquo;&lt;/p&gt;</description></item><item><title>Lesson 7: Lifetimes in Structs — References That Live in Types</title><link>/post/rust/rust-own-struct-lifetimes/</link><pubDate>Mon, 27 May 2024 10:42:00 +0000</pubDate><guid>/post/rust/rust-own-struct-lifetimes/</guid><description>&lt;p&gt;Putting a reference inside a struct is where lifetimes go from &amp;ldquo;mildly confusing&amp;rdquo; to &amp;ldquo;wait, what?&amp;rdquo; for most people. I remember spending an entire afternoon trying to make a struct hold a &lt;code&gt;&amp;amp;str&lt;/code&gt; and wondering why the compiler kept yelling at me.&lt;/p&gt;
&lt;p&gt;The fundamental tension: structs outlive function calls. References might not. The compiler needs you to prove the reference won&amp;rsquo;t dangle.&lt;/p&gt;
&lt;h2 id="the-problem"&gt;The Problem&lt;/h2&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:#75715e"&gt;// This won&amp;#39;t compile
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Excerpt&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; content: &lt;span style="color:#66d9ef"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;str&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;error[E0106]: missing lifetime specifier
 --&amp;gt; src/main.rs:2:14
 |
2 | content: &amp;amp;str,
 | ^ expected named lifetime parameter
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Why? Because the compiler needs to know: how long does the thing &lt;code&gt;content&lt;/code&gt; points to live? Without that information, it can&amp;rsquo;t guarantee the reference is valid for the struct&amp;rsquo;s entire lifetime.&lt;/p&gt;</description></item><item><title>Lesson 6: Lifetime Elision Rules — Why You Usually Don't Write 'a</title><link>/post/rust/rust-own-lifetime-elision/</link><pubDate>Sat, 25 May 2024 19:08:00 +0000</pubDate><guid>/post/rust/rust-own-lifetime-elision/</guid><description>&lt;p&gt;If lifetimes are so important, why don&amp;rsquo;t you see &lt;code&gt;'a&lt;/code&gt; plastered all over most Rust code? Because the compiler is smart enough to figure it out 90% of the time.&lt;/p&gt;
&lt;p&gt;Early Rust required explicit lifetime annotations on every function that dealt with references. The community quickly realized that the same patterns showed up over and over. So the Rust team codified those patterns into &amp;ldquo;elision rules&amp;rdquo; — three rules that let the compiler infer lifetimes automatically.&lt;/p&gt;</description></item><item><title>Lesson 5: Lifetime Annotations — Teaching the Compiler Relationships</title><link>/post/rust/rust-own-lifetime-annotations/</link><pubDate>Thu, 23 May 2024 08:55:00 +0000</pubDate><guid>/post/rust/rust-own-lifetime-annotations/</guid><description>&lt;p&gt;Lifetime annotations are where most people&amp;rsquo;s Rust learning hits a wall. The syntax looks alien. The error messages talk about &amp;ldquo;named lifetimes.&amp;rdquo; Your code compiles fine until you add a second reference parameter, and then suddenly the compiler wants you to annotate things with &lt;code&gt;'a&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the thing most tutorials get wrong: lifetime annotations don&amp;rsquo;t change how long anything lives. They describe relationships that already exist.&lt;/p&gt;
&lt;h2 id="why-lifetimes-exist"&gt;Why Lifetimes Exist&lt;/h2&gt;
&lt;p&gt;Consider this function:&lt;/p&gt;</description></item><item><title>Lesson 4: The Borrow Checker — What It's Really Doing</title><link>/post/rust/rust-own-borrow-checker/</link><pubDate>Tue, 21 May 2024 16:33:00 +0000</pubDate><guid>/post/rust/rust-own-borrow-checker/</guid><description>&lt;p&gt;I used to think the borrow checker was my enemy. It rejected valid programs! It made simple things hard! It was too conservative!&lt;/p&gt;
&lt;p&gt;Then I started maintaining a large C++ codebase and found three use-after-free bugs in one week. The borrow checker stopped looking like an enemy real fast.&lt;/p&gt;
&lt;h2 id="borrowing-using-without-owning"&gt;Borrowing: Using Without Owning&lt;/h2&gt;
&lt;p&gt;Ownership transfer is clean but inflexible. You can&amp;rsquo;t always afford to give your data away — sometimes you just want to let another function &lt;em&gt;look at it&lt;/em&gt; for a moment. That&amp;rsquo;s borrowing.&lt;/p&gt;</description></item><item><title>Lesson 3: Copy vs Clone — When Data Gets Duplicated</title><link>/post/rust/rust-own-copy-clone/</link><pubDate>Sun, 19 May 2024 11:10:00 +0000</pubDate><guid>/post/rust/rust-own-copy-clone/</guid><description>&lt;p&gt;A coworker once asked me: &amp;ldquo;If Rust moves everything, how do I ever use a value twice?&amp;rdquo; Fair question. The answer is two traits that look similar but behave very differently — &lt;code&gt;Copy&lt;/code&gt; and &lt;code&gt;Clone&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Getting these confused will either tank your performance or confuse the hell out of you. Probably both.&lt;/p&gt;
&lt;h2 id="copy-implicit-cheap-and-bitwise"&gt;Copy: Implicit, Cheap, and Bitwise&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Copy&lt;/code&gt; is a marker trait. It tells the compiler: &amp;ldquo;this type is so cheap to duplicate that you should do it automatically on assignment instead of moving.&amp;rdquo;&lt;/p&gt;</description></item><item><title>Lesson 2: Move Semantics — Why Assignment Transfers Ownership</title><link>/post/rust/rust-own-move-semantics/</link><pubDate>Fri, 17 May 2024 14:45:00 +0000</pubDate><guid>/post/rust/rust-own-move-semantics/</guid><description>&lt;p&gt;The first time Rust told me I couldn&amp;rsquo;t use a variable after assigning it to another one, I stared at my screen for a solid minute. In what universe does &lt;code&gt;let b = a&lt;/code&gt; make &lt;code&gt;a&lt;/code&gt; invalid?&lt;/p&gt;
&lt;p&gt;This universe. Rust&amp;rsquo;s universe. And honestly — it&amp;rsquo;s the only sane default.&lt;/p&gt;
&lt;h2 id="what-a-move-actually-is"&gt;What a Move Actually Is&lt;/h2&gt;
&lt;p&gt;In most languages, &lt;code&gt;let b = a&lt;/code&gt; copies the data or copies a reference. In Rust, for heap-allocated types, it &lt;em&gt;moves&lt;/em&gt; the ownership. The bits get copied (the stack portion — pointer, length, capacity), but the old variable is invalidated.&lt;/p&gt;</description></item><item><title>Lesson 1: The Mental Model — Stack, Heap, and Ownership</title><link>/post/rust/rust-own-mental-model/</link><pubDate>Wed, 15 May 2024 09:22:00 +0000</pubDate><guid>/post/rust/rust-own-mental-model/</guid><description>&lt;p&gt;I spent my first three months in Rust confused about ownership. Not because the concept is hard — it&amp;rsquo;s genuinely simple — but because every tutorial I read explained it through the lens of &amp;ldquo;rules to memorize.&amp;rdquo; Three rules. Memorize them. Move on.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s backwards. You don&amp;rsquo;t learn ownership by memorizing rules. You learn it by understanding where your data actually lives.&lt;/p&gt;
&lt;h2 id="where-data-lives-changes-everything"&gt;Where Data Lives Changes Everything&lt;/h2&gt;
&lt;p&gt;Every value in your program sits in one of two places: the stack or the heap. If you&amp;rsquo;ve done any C or C++, this is familiar territory. If you haven&amp;rsquo;t — don&amp;rsquo;t worry, this isn&amp;rsquo;t as scary as systems programmers make it sound.&lt;/p&gt;</description></item></channel></rss>