spellcheck intro + 3 first chapters
This commit is contained in:
@@ -80,7 +80,7 @@
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="affix"><a href="introduction.html">Introduction</a></li><li><a href="1_background_information.html"><strong aria-hidden="true">1.</strong> Some background information</a></li><li><a href="2_trait_objects.html"><strong aria-hidden="true">2.</strong> Trait objects and fat pointers</a></li><li><a href="3_generators_pin.html"><strong aria-hidden="true">3.</strong> Generators and Pin</a></li><li><a href="4_pin.html"><strong aria-hidden="true">4.</strong> Pin</a></li><li><a href="6_future_example.html"><strong aria-hidden="true">5.</strong> The main example</a></li><li><a href="8_finished_example.html"><strong aria-hidden="true">6.</strong> Finished example (editable)</a></li><li class="affix"><a href="conclusion.html">Conclusion and exercises</a></li></ol>
|
||||
<ol class="chapter"><li class="affix"><a href="introduction.html">Introduction</a></li><li><a href="1_background_information.html"><strong aria-hidden="true">1.</strong> Some background information</a></li><li><a href="2_trait_objects.html"><strong aria-hidden="true">2.</strong> Trait objects and fat pointers</a></li><li><a href="3_generators_pin.html"><strong aria-hidden="true">3.</strong> Generators</a></li><li><a href="4_pin.html"><strong aria-hidden="true">4.</strong> Pin</a></li><li><a href="6_future_example.html"><strong aria-hidden="true">5.</strong> The main example</a></li><li><a href="8_finished_example.html"><strong aria-hidden="true">6.</strong> Finished example (editable)</a></li><li class="affix"><a href="conclusion.html">Conclusion and exercises</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
@@ -455,7 +455,7 @@ a callback-based approach, where each closure stores all the data it needs
|
||||
for computation. This means that as we chain these, the memory required to store
|
||||
the needed state increases with each added step.</p>
|
||||
<h3><a class="header" href="#stackless-coroutinesgenerators" id="stackless-coroutinesgenerators">Stackless coroutines/generators</a></h3>
|
||||
<p>This is the model used in Rust today. It a few notable advantages:</p>
|
||||
<p>This is the model used in Rust today. It has a few notable advantages:</p>
|
||||
<ol>
|
||||
<li>It's easy to convert normal Rust code to a stackless coroutine using using
|
||||
async/await as keywords (it can even be done using a macro).</li>
|
||||
@@ -648,7 +648,7 @@ impl Generator for GeneratorA {
|
||||
<p>If you try to compile this you'll get an error (just try it yourself by pressing play).</p>
|
||||
<p>What is the lifetime of <code>&String</code>. It's not the same as the lifetime of <code>Self</code>. It's not <code>static</code>.
|
||||
Turns out that it's not possible for us in Rusts syntax to describe this lifetime, which means, that
|
||||
to make this work, we'll have to let the compiler know that <em>we</em> control this correct.</p>
|
||||
to make this work, we'll have to let the compiler know that <em>we</em> control this correctly ourselves.</p>
|
||||
<p>That means turning to unsafe.</p>
|
||||
<p>Let's try to write an implementation that will compiler using <code>unsafe</code>. As you'll
|
||||
see we end up in a <em>self referential struct</em>. A struct which holds references
|
||||
@@ -711,7 +711,7 @@ impl Generator for GeneratorA {
|
||||
let borrowed = &to_borrow;
|
||||
let res = borrowed.len();
|
||||
|
||||
// Tricks to actually get a self reference
|
||||
// Trick to actually get a self reference
|
||||
*self = GeneratorA::Yield1 {to_borrow, borrowed: std::ptr::null()};
|
||||
match self {
|
||||
GeneratorA::Yield1{to_borrow, borrowed} => *borrowed = to_borrow,
|
||||
@@ -733,10 +733,10 @@ impl Generator for GeneratorA {
|
||||
}
|
||||
</code></pre></pre>
|
||||
<blockquote>
|
||||
<p>Try to uncomment the line with <code>mem::swap</code> and see the result of running this code.</p>
|
||||
<p>Try to uncomment the line with <code>mem::swap</code> and see the results.</p>
|
||||
</blockquote>
|
||||
<p>While the example above compiles just fine, we expose users of this code to
|
||||
both possible undefined behavior and other memory errors while using just safe
|
||||
<p>While the example above compiles just fine, we expose consumers of this this API
|
||||
to both possible undefined behavior and other memory errors while using just safe
|
||||
Rust. This is a big problem!</p>
|
||||
<p>But now, let's prevent the segfault from happening using <code>Pin</code>. We'll discuss
|
||||
<code>Pin</code> more below, but you'll get an introduction here by just reading the
|
||||
@@ -852,15 +852,16 @@ impl Generator for GeneratorA {
|
||||
}
|
||||
}
|
||||
</code></pre></pre>
|
||||
<p>Now, as you see, the user of this code must either:</p>
|
||||
<p>Now, as you see, the consumer of this API must either:</p>
|
||||
<ol>
|
||||
<li>Box the value and thereby allocating it on the heap</li>
|
||||
<li>Use <code>unsafe</code> and pin the value to the stack. The user knows that if they move
|
||||
the value afterwards it will violate the guarantee they promise to uphold when
|
||||
they did their unsafe implementation.</li>
|
||||
</ol>
|
||||
<p>Now, the code which is created and the need for <code>Pin</code> to allow for borrowing
|
||||
across <code>yield</code> points should be pretty clear.</p>
|
||||
<p>Hopefully, after this you'll have an idea of what happens when you use the
|
||||
<code>yield</code> or <code>await</code> keyword (inside an async function) why we need <code>Pin</code> if we
|
||||
want to be able to borrow across <code>yield/await</code> points.</p>
|
||||
<h1><a class="header" href="#pin" id="pin">Pin</a></h1>
|
||||
<blockquote>
|
||||
<p><strong>Relevant for</strong></p>
|
||||
@@ -911,7 +912,7 @@ Moving such a type can cause the universe to crash. As of the time of writing
|
||||
this book, creating an reading fields of a self referential struct still requires <code>unsafe</code>.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>You're not really meant to be implementing <code>MustStay</code>, but you can on nightly with a feature flag, or by adding <code>std::marker::PhantomPinned</code> to your type.</p>
|
||||
<p>You can add a <code>MustStay</code> bound on a type by nightly with a feature flag, or by adding <code>std::marker::PhantomPinned</code> to your type.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>When Pinning, you can either pin a value to memory either on the stack or
|
||||
@@ -1504,8 +1505,8 @@ fn main() {
|
||||
// - first parameter is the `reactor`
|
||||
// - the second is a timeout in seconds
|
||||
// - the third is an `id` to identify the task
|
||||
let future1 = Task::new(reactor.clone(), 2, 1);
|
||||
let future2 = Task::new(reactor.clone(), 1, 2);
|
||||
let future1 = Task::new(reactor.clone(), 1, 1);
|
||||
let future2 = Task::new(reactor.clone(), 2, 2);
|
||||
|
||||
// an `async` block works the same way as an `async fn` in that it compiles
|
||||
// our code into a state machine, `yielding` at every `await` point.
|
||||
@@ -1802,8 +1803,12 @@ fn main() {
|
||||
let reactor = Reactor::new();
|
||||
let reactor = Arc::new(Mutex::new(reactor));
|
||||
|
||||
let future1 = Task::new(reactor.clone(), 2, 1);
|
||||
let future2 = Task::new(reactor.clone(), 1, 2);
|
||||
let future1 = Task::new(reactor.clone(), 1, 1);
|
||||
|
||||
|
||||
|
||||
|
||||
let future2 = Task::new(reactor.clone(), 2, 2);
|
||||
|
||||
let fut1 = async {
|
||||
let val = future1.await;
|
||||
|
||||
Reference in New Issue
Block a user