<buttonid="sidebar-toggle"class="icon-button"type="button"title="Toggle Table of Contents"aria-label="Toggle Table of Contents"aria-controls="sidebar">
<ahref="print.html"title="Print this book"aria-label="Print this book">
<iid="print-button"class="fa fa-print"></i>
</a>
</div>
</div>
<divid="search-wrapper"class="hidden">
<formid="searchbar-outer"class="searchbar-outer">
<inputtype="search"name="search"id="searchbar"name="searchbar"placeholder="Search this book ..."aria-controls="searchresults-outer"aria-describedby="searchresults-header">
let user_name = String::from("User MacUserson");
takes_a_string(user_name);
also_takes_a_string(user_name); // ⚠️
}
</code></pre></pre>
<p>After <code>takes_a_string</code> takes <code>user_name</code>, you can't use it anymore. Here that is no problem: you can just give it <code>user_name.clone()</code>. But sometimes a variable is part of a struct, and maybe you can't clone the struct. Or maybe the <code>String</code> is really long and you don't want to clone it. These are some reasons for <code>Rc</code>, which lets you have more than one owner. An <code>Rc</code> is like a good office worker: <code>Rc</code> writes down who has ownership, and how many. Then once the number of owners goes down to 0, the variable can disappear.</p>
<p>Here's how you use an <code>Rc</code>. First imagine two structs: one called <code>City</code>, and another called <code>CityData</code>. <code>City</code> has information for one city, and <code>CityData</code> puts all the cities together in <code>Vec</code>s.</p>
city_history: "Calgary began as a fort called Fort Calgary that...".to_string(),
};
let canada_cities = CityData {
names: vec![calgary.name], // This is using calgary.name, which is short
histories: vec![calgary.city_history], // But this String is very long
};
println!("Calgary's history is: {}", calgary.city_history); // ⚠️
}
</code></pre></pre>
<p>Of course, it doesn't work because <code>canada_cities</code> now owns the data and <code>calgary</code> doesn't. It says:</p>
<pre><codeclass="language-text">error[E0382]: borrow of moved value: `calgary.city_history`
--> src\main.rs:27:42
|
24 | histories: vec![calgary.city_history], // But this String is very long
| -------------------- value moved here
...
27 | println!("Calgary's history is: {}", calgary.city_history); // ⚠️
| ^^^^^^^^^^^^^^^^^^^^ value borrowed here after move
|
= note: move occurs because `calgary.city_history` has type `std::string::String`, which does not implement the `Copy` trait
</code></pre>
<p>We can clone the name: <code>names: vec![calgary.name.clone()]</code> but we don't want to clone the <code>city_history</code>, which is long. So we can use an <code>Rc</code>.</p>
<p>To add a new reference, you have to <code>clone</code> the <code>Rc</code>. But hold on, didn't we want to avoid using <code>.clone()</code>? Not exactly: we didn't want to clone the whole String. But a clone of an <code>Rc</code> just clones the pointer - it's basically free. It's like putting a name sticker on a box of books to show that two people own it, instead of making a whole new box.</p>
<p>You can clone an <code>Rc</code> called <code>item</code> with <code>item.clone()</code> or with <code>Rc::clone(&item)</code>. So calgary.city_history has 2 owners. We can check the number of owners with <code>Rc::strong_count(&item)</code>. Also let's add a new owner. Now our code looks like this:</p>
<p>This prints <code>2</code>. And <code>new_owner</code> is now an <code>Rc<String></code>. Now if we use <code>println!("{}", Rc::strong_count(&calgary.city_history));</code>, we get <code>3</code>.</p>
<p>So if there are strong pointers, are there weak pointers? Yes, there are. Weak pointers are useful because if two <code>Rc</code>s point at each other, they can't die. This is called a "reference cycle". If item 1 has an Rc to item 2, and item 2 has an Rc to item 1, they can't get to 0. In this case you want to use weak references. Then <code>Rc</code> will count the references, but if it only has weak references then it can die. You use <code>Rc::downgrade(&item)</code> instead of <code>Rc::clone(&item)</code> to make weak references. Also, you use <code>Rc::weak_count(&item)</code> to see the weak count.</p>