281 lines
No EOL
18 KiB
HTML
281 lines
No EOL
18 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 `cell` mod in crate `bitflags`.">
|
||
<meta name="keywords" content="rust, rustlang, rust-lang, cell">
|
||
|
||
<title>bitflags::__core::cell - 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: 'cell', 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=''>cell</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-28153' class='srclink' href='https://doc.rust-lang.org/nightly/core/cell/index.html?gotosrc=28153' title='goto source code'>[src]</a></span></h1>
|
||
<div class='docblock'><p>Shareable mutable containers.</p>
|
||
|
||
<p>Values of the <code>Cell<T></code> and <code>RefCell<T></code> types may be mutated through shared references (i.e.
|
||
the common <code>&T</code> type), whereas most Rust types can only be mutated through unique (<code>&mut T</code>)
|
||
references. We say that <code>Cell<T></code> and <code>RefCell<T></code> provide 'interior mutability', in contrast
|
||
with typical Rust types that exhibit 'inherited mutability'.</p>
|
||
|
||
<p>Cell types come in two flavors: <code>Cell<T></code> and <code>RefCell<T></code>. <code>Cell<T></code> provides <code>get</code> and <code>set</code>
|
||
methods that change the interior value with a single method call. <code>Cell<T></code> though is only
|
||
compatible with types that implement <code>Copy</code>. For other types, one must use the <code>RefCell<T></code>
|
||
type, acquiring a write lock before mutating.</p>
|
||
|
||
<p><code>RefCell<T></code> uses Rust's lifetimes to implement 'dynamic borrowing', a process whereby one can
|
||
claim temporary, exclusive, mutable access to the inner value. Borrows for <code>RefCell<T></code>s are
|
||
tracked 'at runtime', unlike Rust's native reference types which are entirely tracked
|
||
statically, at compile time. Because <code>RefCell<T></code> borrows are dynamic it is possible to attempt
|
||
to borrow a value that is already mutably borrowed; when this happens it results in thread
|
||
panic.</p>
|
||
|
||
<h1 id='when-to-choose-interior-mutability' class='section-header'><a href='#when-to-choose-interior-mutability'>When to choose interior mutability</a></h1>
|
||
<p>The more common inherited mutability, where one must have unique access to mutate a value, is
|
||
one of the key language elements that enables Rust to reason strongly about pointer aliasing,
|
||
statically preventing crash bugs. Because of that, inherited mutability is preferred, and
|
||
interior mutability is something of a last resort. Since cell types enable mutation where it
|
||
would otherwise be disallowed though, there are occasions when interior mutability might be
|
||
appropriate, or even <em>must</em> be used, e.g.</p>
|
||
|
||
<ul>
|
||
<li>Introducing mutability 'inside' of something immutable</li>
|
||
<li>Implementation details of logically-immutable methods.</li>
|
||
<li>Mutating implementations of <code>Clone</code>.</li>
|
||
</ul>
|
||
|
||
<h2 id='introducing-mutability-inside-of-something-immutable' class='section-header'><a href='#introducing-mutability-inside-of-something-immutable'>Introducing mutability 'inside' of something immutable</a></h2>
|
||
<p>Many shared smart pointer types, including <code>Rc<T></code> and <code>Arc<T></code>, provide containers that can be
|
||
cloned and shared between multiple parties. Because the contained values may be
|
||
multiply-aliased, they can only be borrowed with <code>&</code>, not <code>&mut</code>. Without cells it would be
|
||
impossible to mutate data inside of these smart pointers at all.</p>
|
||
|
||
<p>It's very common then to put a <code>RefCell<T></code> inside shared pointer types to reintroduce
|
||
mutability:</p>
|
||
|
||
<pre class='rust rust-example-rendered'>
|
||
<span class='kw'>use</span> <span class='ident'>std</span>::<span class='ident'>collections</span>::<span class='ident'>HashMap</span>;
|
||
<span class='kw'>use</span> <span class='ident'>std</span>::<span class='ident'>cell</span>::<span class='ident'>RefCell</span>;
|
||
<span class='kw'>use</span> <span class='ident'>std</span>::<span class='ident'>rc</span>::<span class='ident'>Rc</span>;
|
||
|
||
<span class='kw'>fn</span> <span class='ident'>main</span>() {
|
||
<span class='kw'>let</span> <span class='ident'>shared_map</span>: <span class='ident'>Rc</span><span class='op'><</span><span class='ident'>RefCell</span><span class='op'><</span>_<span class='op'>>></span> <span class='op'>=</span> <span class='ident'>Rc</span>::<span class='ident'>new</span>(<span class='ident'>RefCell</span>::<span class='ident'>new</span>(<span class='ident'>HashMap</span>::<span class='ident'>new</span>()));
|
||
<span class='ident'>shared_map</span>.<span class='ident'>borrow_mut</span>().<span class='ident'>insert</span>(<span class='string'>"africa"</span>, <span class='number'>92388</span>);
|
||
<span class='ident'>shared_map</span>.<span class='ident'>borrow_mut</span>().<span class='ident'>insert</span>(<span class='string'>"kyoto"</span>, <span class='number'>11837</span>);
|
||
<span class='ident'>shared_map</span>.<span class='ident'>borrow_mut</span>().<span class='ident'>insert</span>(<span class='string'>"piccadilly"</span>, <span class='number'>11826</span>);
|
||
<span class='ident'>shared_map</span>.<span class='ident'>borrow_mut</span>().<span class='ident'>insert</span>(<span class='string'>"marbles"</span>, <span class='number'>38</span>);
|
||
}</pre>
|
||
|
||
<p>Note that this example uses <code>Rc<T></code> and not <code>Arc<T></code>. <code>RefCell<T></code>s are for single-threaded
|
||
scenarios. Consider using <code>RwLock<T></code> or <code>Mutex<T></code> if you need shared mutability in a
|
||
multi-threaded situation.</p>
|
||
|
||
<h2 id='implementation-details-of-logically-immutable-methods' class='section-header'><a href='#implementation-details-of-logically-immutable-methods'>Implementation details of logically-immutable methods</a></h2>
|
||
<p>Occasionally it may be desirable not to expose in an API that there is mutation happening
|
||
"under the hood". This may be because logically the operation is immutable, but e.g. caching
|
||
forces the implementation to perform mutation; or because you must employ mutation to implement
|
||
a trait method that was originally defined to take <code>&self</code>.</p>
|
||
|
||
<pre class='rust rust-example-rendered'>
|
||
<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'>Graph</span> {
|
||
<span class='ident'>edges</span>: <span class='ident'>Vec</span><span class='op'><</span>(<span class='ident'>i32</span>, <span class='ident'>i32</span>)<span class='op'>></span>,
|
||
<span class='ident'>span_tree_cache</span>: <span class='ident'>RefCell</span><span class='op'><</span><span class='prelude-ty'>Option</span><span class='op'><</span><span class='ident'>Vec</span><span class='op'><</span>(<span class='ident'>i32</span>, <span class='ident'>i32</span>)<span class='op'>>></span><span class='op'>></span>
|
||
}
|
||
|
||
<span class='kw'>impl</span> <span class='ident'>Graph</span> {
|
||
<span class='kw'>fn</span> <span class='ident'>minimum_spanning_tree</span>(<span class='kw-2'>&</span><span class='self'>self</span>) <span class='op'>-></span> <span class='ident'>Vec</span><span class='op'><</span>(<span class='ident'>i32</span>, <span class='ident'>i32</span>)<span class='op'>></span> {
|
||
<span class='comment'>// Create a new scope to contain the lifetime of the</span>
|
||
<span class='comment'>// dynamic borrow</span>
|
||
{
|
||
<span class='comment'>// Take a reference to the inside of cache cell</span>
|
||
<span class='kw'>let</span> <span class='kw-2'>mut</span> <span class='ident'>cache</span> <span class='op'>=</span> <span class='self'>self</span>.<span class='ident'>span_tree_cache</span>.<span class='ident'>borrow_mut</span>();
|
||
<span class='kw'>if</span> <span class='ident'>cache</span>.<span class='ident'>is_some</span>() {
|
||
<span class='kw'>return</span> <span class='ident'>cache</span>.<span class='ident'>as_ref</span>().<span class='ident'>unwrap</span>().<span class='ident'>clone</span>();
|
||
}
|
||
|
||
<span class='kw'>let</span> <span class='ident'>span_tree</span> <span class='op'>=</span> <span class='self'>self</span>.<span class='ident'>calc_span_tree</span>();
|
||
<span class='op'>*</span><span class='ident'>cache</span> <span class='op'>=</span> <span class='prelude-val'>Some</span>(<span class='ident'>span_tree</span>);
|
||
}
|
||
|
||
<span class='comment'>// Recursive call to return the just-cached value.</span>
|
||
<span class='comment'>// Note that if we had not let the previous borrow</span>
|
||
<span class='comment'>// of the cache fall out of scope then the subsequent</span>
|
||
<span class='comment'>// recursive borrow would cause a dynamic thread panic.</span>
|
||
<span class='comment'>// This is the major hazard of using `RefCell`.</span>
|
||
<span class='self'>self</span>.<span class='ident'>minimum_spanning_tree</span>()
|
||
}
|
||
}</pre>
|
||
|
||
<h2 id='mutating-implementations-of-clone' class='section-header'><a href='#mutating-implementations-of-clone'>Mutating implementations of <code>Clone</code></a></h2>
|
||
<p>This is simply a special - but common - case of the previous: hiding mutability for operations
|
||
that appear to be immutable. The <code>clone</code> method is expected to not change the source value, and
|
||
is declared to take <code>&self</code>, not <code>&mut self</code>. Therefore any mutation that happens in the
|
||
<code>clone</code> method must use cell types. For example, <code>Rc<T></code> maintains its reference counts within a
|
||
<code>Cell<T></code>.</p>
|
||
|
||
<pre class='rust rust-example-rendered'>
|
||
<span class='kw'>use</span> <span class='ident'>std</span>::<span class='ident'>cell</span>::<span class='ident'>Cell</span>;
|
||
|
||
<span class='kw'>struct</span> <span class='ident'>Rc</span><span class='op'><</span><span class='ident'>T</span><span class='op'>></span> {
|
||
<span class='ident'>ptr</span>: <span class='op'>*</span><span class='kw-2'>mut</span> <span class='ident'>RcBox</span><span class='op'><</span><span class='ident'>T</span><span class='op'>></span>
|
||
}
|
||
|
||
<span class='kw'>struct</span> <span class='ident'>RcBox</span><span class='op'><</span><span class='ident'>T</span><span class='op'>></span> {
|
||
<span class='ident'>value</span>: <span class='ident'>T</span>,
|
||
<span class='ident'>refcount</span>: <span class='ident'>Cell</span><span class='op'><</span><span class='ident'>usize</span><span class='op'>></span>
|
||
}
|
||
|
||
<span class='kw'>impl</span><span class='op'><</span><span class='ident'>T</span><span class='op'>></span> <span class='ident'>Clone</span> <span class='kw'>for</span> <span class='ident'>Rc</span><span class='op'><</span><span class='ident'>T</span><span class='op'>></span> {
|
||
<span class='kw'>fn</span> <span class='ident'>clone</span>(<span class='kw-2'>&</span><span class='self'>self</span>) <span class='op'>-></span> <span class='ident'>Rc</span><span class='op'><</span><span class='ident'>T</span><span class='op'>></span> {
|
||
<span class='kw'>unsafe</span> {
|
||
(<span class='op'>*</span><span class='self'>self</span>.<span class='ident'>ptr</span>).<span class='ident'>refcount</span>.<span class='ident'>set</span>((<span class='op'>*</span><span class='self'>self</span>.<span class='ident'>ptr</span>).<span class='ident'>refcount</span>.<span class='ident'>get</span>() <span class='op'>+</span> <span class='number'>1</span>);
|
||
<span class='ident'>Rc</span> { <span class='ident'>ptr</span>: <span class='self'>self</span>.<span class='ident'>ptr</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.Cell.html'
|
||
title='bitflags::__core::cell::Cell'>Cell</a></td>
|
||
<td class='docblock short'>
|
||
<p>A mutable memory location that admits only <code>Copy</code> data.</p>
|
||
</td>
|
||
</tr>
|
||
<tr class=' module-item'>
|
||
<td><a class='struct' href='struct.Ref.html'
|
||
title='bitflags::__core::cell::Ref'>Ref</a></td>
|
||
<td class='docblock short'>
|
||
<p>Wraps a borrowed reference to a value in a <code>RefCell</code> box.
|
||
A wrapper type for an immutably borrowed value from a <code>RefCell<T></code>.</p>
|
||
</td>
|
||
</tr>
|
||
<tr class=' module-item'>
|
||
<td><a class='struct' href='struct.RefCell.html'
|
||
title='bitflags::__core::cell::RefCell'>RefCell</a></td>
|
||
<td class='docblock short'>
|
||
<p>A mutable memory location with dynamically checked borrow rules</p>
|
||
</td>
|
||
</tr>
|
||
<tr class=' module-item'>
|
||
<td><a class='struct' href='struct.RefMut.html'
|
||
title='bitflags::__core::cell::RefMut'>RefMut</a></td>
|
||
<td class='docblock short'>
|
||
<p>A wrapper type for a mutably borrowed value from a <code>RefCell<T></code>.</p>
|
||
</td>
|
||
</tr>
|
||
<tr class=' module-item'>
|
||
<td><a class='struct' href='struct.UnsafeCell.html'
|
||
title='bitflags::__core::cell::UnsafeCell'>UnsafeCell</a></td>
|
||
<td class='docblock short'>
|
||
<p>The core primitive for interior mutability in Rust.</p>
|
||
</td>
|
||
</tr></table><h2 id='enums' class='section-header'><a href="#enums">Enums</a></h2>
|
||
<table>
|
||
<tr class='unstable module-item'>
|
||
<td><a class='enum' href='enum.BorrowState.html'
|
||
title='bitflags::__core::cell::BorrowState'>BorrowState</a></td>
|
||
<td class='docblock short'>
|
||
[<em class='stab unstable'>Unstable</em>] <p>An enumeration of values returned from the <code>state</code> method on a <code>RefCell<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> |