261 lines
No EOL
16 KiB
HTML
261 lines
No EOL
16 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="generator" content="rustdoc">
|
||
<meta name="description" content="API documentation for the Rust `rc` mod in crate `bitflags`.">
|
||
<meta name="keywords" content="rust, rustlang, rust-lang, rc">
|
||
|
||
<title>bitflags::__core::rc - Rust</title>
|
||
|
||
<link rel="stylesheet" type="text/css" href="../../../rustdoc.css">
|
||
<link rel="stylesheet" type="text/css" href="../../../main.css">
|
||
|
||
|
||
|
||
|
||
</head>
|
||
<body class="rustdoc">
|
||
<!--[if lte IE 8]>
|
||
<div class="warning">
|
||
This old browser is unsupported and will most likely display funky
|
||
things.
|
||
</div>
|
||
<![endif]-->
|
||
|
||
|
||
|
||
<nav class="sidebar">
|
||
|
||
<p class='location'><a href='../../index.html'>bitflags</a>::<wbr><a href='../index.html'>__core</a></p><script>window.sidebarCurrent = {name: 'rc', ty: 'mod', relpath: '../'};</script><script defer src="../sidebar-items.js"></script>
|
||
</nav>
|
||
|
||
<nav class="sub">
|
||
<form class="search-form js-only">
|
||
<div class="search-container">
|
||
<input class="search-input" name="search"
|
||
autocomplete="off"
|
||
placeholder="Click or press ‘S’ to search, ‘?’ for more options…"
|
||
type="search">
|
||
</div>
|
||
</form>
|
||
</nav>
|
||
|
||
<section id='main' class="content mod">
|
||
<h1 class='fqn'><span class='in-band'>Module <a href='../../index.html'>bitflags</a>::<wbr><a href='../index.html'>__core</a>::<wbr><a class='mod' href=''>rc</a></span><span class='out-of-band'><span id='render-detail'>
|
||
<a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">
|
||
[<span class='inner'>−</span>]
|
||
</a>
|
||
</span><a id='src-536' class='srclink' href='https://doc.rust-lang.org/nightly/alloc/rc/index.html?gotosrc=536' title='goto source code'>[src]</a></span></h1>
|
||
<div class='docblock'><p>Thread-local reference-counted boxes (the <code>Rc<T></code> type).</p>
|
||
|
||
<p>The <code>Rc<T></code> type provides shared ownership of an immutable value.
|
||
Destruction is deterministic, and will occur as soon as the last owner is
|
||
gone. It is marked as non-sendable because it avoids the overhead of atomic
|
||
reference counting.</p>
|
||
|
||
<p>The <code>downgrade</code> method can be used to create a non-owning <code>Weak<T></code> pointer
|
||
to the box. A <code>Weak<T></code> pointer can be upgraded to an <code>Rc<T></code> pointer, but
|
||
will return <code>None</code> if the value has already been dropped.</p>
|
||
|
||
<p>For example, a tree with parent pointers can be represented by putting the
|
||
nodes behind strong <code>Rc<T></code> pointers, and then storing the parent pointers
|
||
as <code>Weak<T></code> pointers.</p>
|
||
|
||
<h1 id='examples' class='section-header'><a href='#examples'>Examples</a></h1>
|
||
<p>Consider a scenario where a set of <code>Gadget</code>s are owned by a given <code>Owner</code>.
|
||
We want to have our <code>Gadget</code>s point to their <code>Owner</code>. We can't do this with
|
||
unique ownership, because more than one gadget may belong to the same
|
||
<code>Owner</code>. <code>Rc<T></code> allows us to share an <code>Owner</code> between multiple <code>Gadget</code>s,
|
||
and have the <code>Owner</code> remain allocated as long as any <code>Gadget</code> points at it.</p>
|
||
|
||
<pre class='rust rust-example-rendered'>
|
||
<span class='kw'>use</span> <span class='ident'>std</span>::<span class='ident'>rc</span>::<span class='ident'>Rc</span>;
|
||
|
||
<span class='kw'>struct</span> <span class='ident'>Owner</span> {
|
||
<span class='ident'>name</span>: <span class='ident'>String</span>
|
||
<span class='comment'>// ...other fields</span>
|
||
}
|
||
|
||
<span class='kw'>struct</span> <span class='ident'>Gadget</span> {
|
||
<span class='ident'>id</span>: <span class='ident'>i32</span>,
|
||
<span class='ident'>owner</span>: <span class='ident'>Rc</span><span class='op'><</span><span class='ident'>Owner</span><span class='op'>></span>
|
||
<span class='comment'>// ...other fields</span>
|
||
}
|
||
|
||
<span class='kw'>fn</span> <span class='ident'>main</span>() {
|
||
<span class='comment'>// Create a reference counted Owner.</span>
|
||
<span class='kw'>let</span> <span class='ident'>gadget_owner</span> : <span class='ident'>Rc</span><span class='op'><</span><span class='ident'>Owner</span><span class='op'>></span> <span class='op'>=</span> <span class='ident'>Rc</span>::<span class='ident'>new</span>(
|
||
<span class='ident'>Owner</span> { <span class='ident'>name</span>: <span class='ident'>String</span>::<span class='ident'>from</span>(<span class='string'>"Gadget Man"</span>) }
|
||
);
|
||
|
||
<span class='comment'>// Create Gadgets belonging to gadget_owner. To increment the reference</span>
|
||
<span class='comment'>// count we clone the `Rc<T>` object.</span>
|
||
<span class='kw'>let</span> <span class='ident'>gadget1</span> <span class='op'>=</span> <span class='ident'>Gadget</span> { <span class='ident'>id</span>: <span class='number'>1</span>, <span class='ident'>owner</span>: <span class='ident'>gadget_owner</span>.<span class='ident'>clone</span>() };
|
||
<span class='kw'>let</span> <span class='ident'>gadget2</span> <span class='op'>=</span> <span class='ident'>Gadget</span> { <span class='ident'>id</span>: <span class='number'>2</span>, <span class='ident'>owner</span>: <span class='ident'>gadget_owner</span>.<span class='ident'>clone</span>() };
|
||
|
||
<span class='ident'>drop</span>(<span class='ident'>gadget_owner</span>);
|
||
|
||
<span class='comment'>// Despite dropping gadget_owner, we're still able to print out the name</span>
|
||
<span class='comment'>// of the Owner of the Gadgets. This is because we've only dropped the</span>
|
||
<span class='comment'>// reference count object, not the Owner it wraps. As long as there are</span>
|
||
<span class='comment'>// other `Rc<T>` objects pointing at the same Owner, it will remain</span>
|
||
<span class='comment'>// allocated. Notice that the `Rc<T>` wrapper around Gadget.owner gets</span>
|
||
<span class='comment'>// automatically dereferenced for us.</span>
|
||
<span class='macro'>println</span><span class='macro'>!</span>(<span class='string'>"Gadget {} owned by {}"</span>, <span class='ident'>gadget1</span>.<span class='ident'>id</span>, <span class='ident'>gadget1</span>.<span class='ident'>owner</span>.<span class='ident'>name</span>);
|
||
<span class='macro'>println</span><span class='macro'>!</span>(<span class='string'>"Gadget {} owned by {}"</span>, <span class='ident'>gadget2</span>.<span class='ident'>id</span>, <span class='ident'>gadget2</span>.<span class='ident'>owner</span>.<span class='ident'>name</span>);
|
||
|
||
<span class='comment'>// At the end of the method, gadget1 and gadget2 get destroyed, and with</span>
|
||
<span class='comment'>// them the last counted references to our Owner. Gadget Man now gets</span>
|
||
<span class='comment'>// destroyed as well.</span>
|
||
}</pre>
|
||
|
||
<p>If our requirements change, and we also need to be able to traverse from
|
||
Owner → Gadget, we will run into problems: an <code>Rc<T></code> pointer from Owner
|
||
→ Gadget introduces a cycle between the objects. This means that their
|
||
reference counts can never reach 0, and the objects will remain allocated: a
|
||
memory leak. In order to get around this, we can use <code>Weak<T></code> pointers.
|
||
These pointers don't contribute to the total count.</p>
|
||
|
||
<p>Rust actually makes it somewhat difficult to produce this loop in the first
|
||
place: in order to end up with two objects that point at each other, one of
|
||
them needs to be mutable. This is problematic because <code>Rc<T></code> enforces
|
||
memory safety by only giving out shared references to the object it wraps,
|
||
and these don't allow direct mutation. We need to wrap the part of the
|
||
object we wish to mutate in a <code>RefCell</code>, which provides <em>interior
|
||
mutability</em>: a method to achieve mutability through a shared reference.
|
||
<code>RefCell</code> enforces Rust's borrowing rules at runtime. Read the <code>Cell</code>
|
||
documentation for more details on interior mutability.</p>
|
||
|
||
<pre class='rust rust-example-rendered'>
|
||
<span class='kw'>use</span> <span class='ident'>std</span>::<span class='ident'>rc</span>::<span class='ident'>Rc</span>;
|
||
<span class='kw'>use</span> <span class='ident'>std</span>::<span class='ident'>rc</span>::<span class='ident'>Weak</span>;
|
||
<span class='kw'>use</span> <span class='ident'>std</span>::<span class='ident'>cell</span>::<span class='ident'>RefCell</span>;
|
||
|
||
<span class='kw'>struct</span> <span class='ident'>Owner</span> {
|
||
<span class='ident'>name</span>: <span class='ident'>String</span>,
|
||
<span class='ident'>gadgets</span>: <span class='ident'>RefCell</span><span class='op'><</span><span class='ident'>Vec</span><span class='op'><</span><span class='ident'>Weak</span><span class='op'><</span><span class='ident'>Gadget</span><span class='op'>>></span><span class='op'>></span>,
|
||
<span class='comment'>// ...other fields</span>
|
||
}
|
||
|
||
<span class='kw'>struct</span> <span class='ident'>Gadget</span> {
|
||
<span class='ident'>id</span>: <span class='ident'>i32</span>,
|
||
<span class='ident'>owner</span>: <span class='ident'>Rc</span><span class='op'><</span><span class='ident'>Owner</span><span class='op'>></span>,
|
||
<span class='comment'>// ...other fields</span>
|
||
}
|
||
|
||
<span class='kw'>fn</span> <span class='ident'>main</span>() {
|
||
<span class='comment'>// Create a reference counted Owner. Note the fact that we've put the</span>
|
||
<span class='comment'>// Owner's vector of Gadgets inside a RefCell so that we can mutate it</span>
|
||
<span class='comment'>// through a shared reference.</span>
|
||
<span class='kw'>let</span> <span class='ident'>gadget_owner</span> : <span class='ident'>Rc</span><span class='op'><</span><span class='ident'>Owner</span><span class='op'>></span> <span class='op'>=</span> <span class='ident'>Rc</span>::<span class='ident'>new</span>(
|
||
<span class='ident'>Owner</span> {
|
||
<span class='ident'>name</span>: <span class='string'>"Gadget Man"</span>.<span class='ident'>to_string</span>(),
|
||
<span class='ident'>gadgets</span>: <span class='ident'>RefCell</span>::<span class='ident'>new</span>(<span class='ident'>Vec</span>::<span class='ident'>new</span>()),
|
||
}
|
||
);
|
||
|
||
<span class='comment'>// Create Gadgets belonging to gadget_owner as before.</span>
|
||
<span class='kw'>let</span> <span class='ident'>gadget1</span> <span class='op'>=</span> <span class='ident'>Rc</span>::<span class='ident'>new</span>(<span class='ident'>Gadget</span>{<span class='ident'>id</span>: <span class='number'>1</span>, <span class='ident'>owner</span>: <span class='ident'>gadget_owner</span>.<span class='ident'>clone</span>()});
|
||
<span class='kw'>let</span> <span class='ident'>gadget2</span> <span class='op'>=</span> <span class='ident'>Rc</span>::<span class='ident'>new</span>(<span class='ident'>Gadget</span>{<span class='ident'>id</span>: <span class='number'>2</span>, <span class='ident'>owner</span>: <span class='ident'>gadget_owner</span>.<span class='ident'>clone</span>()});
|
||
|
||
<span class='comment'>// Add the Gadgets to their Owner. To do this we mutably borrow from</span>
|
||
<span class='comment'>// the RefCell holding the Owner's Gadgets.</span>
|
||
<span class='ident'>gadget_owner</span>.<span class='ident'>gadgets</span>.<span class='ident'>borrow_mut</span>().<span class='ident'>push</span>(<span class='ident'>Rc</span>::<span class='ident'>downgrade</span>(<span class='kw-2'>&</span><span class='ident'>gadget1</span>));
|
||
<span class='ident'>gadget_owner</span>.<span class='ident'>gadgets</span>.<span class='ident'>borrow_mut</span>().<span class='ident'>push</span>(<span class='ident'>Rc</span>::<span class='ident'>downgrade</span>(<span class='kw-2'>&</span><span class='ident'>gadget2</span>));
|
||
|
||
<span class='comment'>// Iterate over our Gadgets, printing their details out</span>
|
||
<span class='kw'>for</span> <span class='ident'>gadget_opt</span> <span class='kw'>in</span> <span class='ident'>gadget_owner</span>.<span class='ident'>gadgets</span>.<span class='ident'>borrow</span>().<span class='ident'>iter</span>() {
|
||
|
||
<span class='comment'>// gadget_opt is a Weak<Gadget>. Since weak pointers can't guarantee</span>
|
||
<span class='comment'>// that their object is still allocated, we need to call upgrade()</span>
|
||
<span class='comment'>// on them to turn them into a strong reference. This returns an</span>
|
||
<span class='comment'>// Option, which contains a reference to our object if it still</span>
|
||
<span class='comment'>// exists.</span>
|
||
<span class='kw'>let</span> <span class='ident'>gadget</span> <span class='op'>=</span> <span class='ident'>gadget_opt</span>.<span class='ident'>upgrade</span>().<span class='ident'>unwrap</span>();
|
||
<span class='macro'>println</span><span class='macro'>!</span>(<span class='string'>"Gadget {} owned by {}"</span>, <span class='ident'>gadget</span>.<span class='ident'>id</span>, <span class='ident'>gadget</span>.<span class='ident'>owner</span>.<span class='ident'>name</span>);
|
||
}
|
||
|
||
<span class='comment'>// At the end of the method, gadget_owner, gadget1 and gadget2 get</span>
|
||
<span class='comment'>// destroyed. There are now no strong (`Rc<T>`) references to the gadgets.</span>
|
||
<span class='comment'>// Once they get destroyed, the Gadgets get destroyed. This zeroes the</span>
|
||
<span class='comment'>// reference count on Gadget Man, they get destroyed as well.</span>
|
||
}</pre>
|
||
</div><h2 id='structs' class='section-header'><a href="#structs">Structs</a></h2>
|
||
<table>
|
||
<tr class=' module-item'>
|
||
<td><a class='struct' href='struct.Rc.html'
|
||
title='bitflags::__core::rc::Rc'>Rc</a></td>
|
||
<td class='docblock short'>
|
||
<p>A reference-counted pointer type over an immutable value.</p>
|
||
</td>
|
||
</tr>
|
||
<tr class=' module-item'>
|
||
<td><a class='struct' href='struct.Weak.html'
|
||
title='bitflags::__core::rc::Weak'>Weak</a></td>
|
||
<td class='docblock short'>
|
||
<p>A weak version of <code>Rc<T></code>.</p>
|
||
</td>
|
||
</tr></table></section>
|
||
<section id='search' class="content hidden"></section>
|
||
|
||
<section class="footer"></section>
|
||
|
||
<aside id="help" class="hidden">
|
||
<div>
|
||
<h1 class="hidden">Help</h1>
|
||
|
||
<div class="shortcuts">
|
||
<h2>Keyboard Shortcuts</h2>
|
||
|
||
<dl>
|
||
<dt>?</dt>
|
||
<dd>Show this help dialog</dd>
|
||
<dt>S</dt>
|
||
<dd>Focus the search field</dd>
|
||
<dt>⇤</dt>
|
||
<dd>Move up in search results</dd>
|
||
<dt>⇥</dt>
|
||
<dd>Move down in search results</dd>
|
||
<dt>⏎</dt>
|
||
<dd>Go to active search result</dd>
|
||
</dl>
|
||
</div>
|
||
|
||
<div class="infos">
|
||
<h2>Search Tricks</h2>
|
||
|
||
<p>
|
||
Prefix searches with a type followed by a colon (e.g.
|
||
<code>fn:</code>) to restrict the search to a given type.
|
||
</p>
|
||
|
||
<p>
|
||
Accepted types are: <code>fn</code>, <code>mod</code>,
|
||
<code>struct</code>, <code>enum</code>,
|
||
<code>trait</code>, <code>type</code>, <code>macro</code>,
|
||
and <code>const</code>.
|
||
</p>
|
||
|
||
<p>
|
||
Search functions by type signature (e.g.
|
||
<code>vec -> usize</code> or <code>* -> vec</code>)
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
|
||
|
||
|
||
<script>
|
||
window.rootPath = "../../../";
|
||
window.currentCrate = "bitflags";
|
||
window.playgroundUrl = "";
|
||
</script>
|
||
<script src="../../../jquery.js"></script>
|
||
<script src="../../../main.js"></script>
|
||
|
||
<script defer src="../../../search-index.js"></script>
|
||
</body>
|
||
</html> |