143 lines
3.7 KiB
HTML
143 lines
3.7 KiB
HTML
<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>
|
|
|
|
|
|
|