This commit is contained in:
parent
394de3ceaa
commit
3df4f2a63f
142
content/decks/rust-lifetimes.html
Normal file
142
content/decks/rust-lifetimes.html
Normal file
|
@ -0,0 +1,142 @@
|
|||
<section>
|
||||
<h2> Lifetimes in Rust </h2>
|
||||
<p> It was always there, but now it's explicit </p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>Recap: References </h3>
|
||||
<ul>
|
||||
<li><code>&MyStruct</code> is a reference/borrow of a struct</li>
|
||||
<li class="fragment">If the underlying struct is <em>removed</em>, the reference is invalid </li>
|
||||
<li class="fragment">In C++, it is entirely on you to manage this</li>
|
||||
<li class="fragment"pre>Rust just makes this management explicit </li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>Motivation</h3>
|
||||
<pre ><code class="rust" data-trim data-line-numbers>
|
||||
let x;
|
||||
{
|
||||
let y = 5;
|
||||
x = &y;
|
||||
} // uh oh
|
||||
println!("x: {}", x); // hmmm
|
||||
</code></pre>
|
||||
<p>Rust will not compile this code</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>Lifetimes</h3>
|
||||
<ul>
|
||||
<li> These always exist. </li>
|
||||
<li class="fragment"> Sometimes the compiler needs some hints </li>
|
||||
<li class="fragment"> We can <em>annotate</em> lifetimes to add hints </li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>Annotation Example</h3>
|
||||
<pre><code class="rust" data-trim data-line-numbers="1-10|12-23"><script type="text/template">
|
||||
// 'a is a generic lifetime parameter. the borrow checker
|
||||
// will infer which lifetime it represents and ensure
|
||||
// that the relationships are valid.
|
||||
fn longer_string<'a>(x: &'a str, y: &'a str) -> &'a str {
|
||||
if x.len() > y.len() {
|
||||
x
|
||||
} else {
|
||||
y
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let string1 = String::from("longer");
|
||||
let result;
|
||||
|
||||
{
|
||||
let string2 = String::from("short");
|
||||
result = longest(&string1, &string2);
|
||||
println("Longest: {}", result);
|
||||
}
|
||||
// can't do this. why?
|
||||
// println("Longest: {}", result);
|
||||
}
|
||||
</script></code></pre>
|
||||
<p class="fragment">The borrow checker will use the shortest lifetime</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>Struct Example</h3>
|
||||
<pre><code class="rust" data-trim data-line-numbers="1-5|7-12"><script type="text/template">
|
||||
// again, 'a is a generic lifetime parameter.
|
||||
struct Keyword<'a> {
|
||||
word: &'a str,
|
||||
parent: &'a str,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let example = String::from("This is the demo text");
|
||||
let demo = example.get(12..16);
|
||||
let kw = Keyword { word: demo, parent: example };
|
||||
// kw cannot outlive demo or example
|
||||
}
|
||||
</script></code></pre>
|
||||
</section>
|
||||
|
||||
|
||||
<section>
|
||||
<section>
|
||||
<h3>Challenge: Circular references</h3>
|
||||
<pre><code class="rust" data-trim data-line-numbers><script type="text/template">
|
||||
struct Node<'a> {
|
||||
data: u32,
|
||||
next: Option<&'a Node<'a>>, // what does this mean?
|
||||
}
|
||||
let mut x = Node {value: 42, next: None };
|
||||
let y = Node { value: 7, next: Some(&x) };
|
||||
// and this is where we perish.
|
||||
x.next = Some(&y);
|
||||
</script></code></pre>
|
||||
</section>
|
||||
<section>
|
||||
<h3>Rc + Refcell</h3>
|
||||
<pre><code class="rust" data-trim data-line-numbers><script type="text/template">
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
struct Node {
|
||||
data: u32,
|
||||
next: Option<Rc<RefCell<Node>>>,
|
||||
}
|
||||
</script></code></pre>
|
||||
<ul>
|
||||
<li> + safety of ownership/mutability at runtime</li>
|
||||
<li> - there is a performance penalty</li>
|
||||
<li> - a bit awkward to use.</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h3>Vec + Index</h3>
|
||||
<pre><code class="rust" data-trim data-line-numbers><script type="text/template">
|
||||
struct Graph {
|
||||
nodes: Vec<Option<Node>>
|
||||
}
|
||||
struct Node {
|
||||
data: u32,
|
||||
next: usize, // index into graph.
|
||||
}
|
||||
</script></code></pre>
|
||||
<ul>
|
||||
<li> + fast, no weird Rc stuff</li>
|
||||
<li> - bug prone, self managed, can dangle </li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h3>3rd party libraries</h3>
|
||||
<p><a href="https://github.com/orlp/slotmap/blob/master/examples/doubly_linked_list.rs">slotmap</a>: Like a hashmap, but with unique keys</p>
|
||||
<p><a href="https://docs.rs/typed-arena/latest/typed_arena/#safe-cycles">typed-arena</a>: Arena allocator. Can only drop the whole arena</p>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
Loading…
Reference in a new issue