Skip to content

Instantly share code, notes, and snippets.

Created December 31, 2016 22:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/efee97eb496d7e5e896ecd9546c00161 to your computer and use it in GitHub Desktop.
Save anonymous/efee97eb496d7e5e896ecd9546c00161 to your computer and use it in GitHub Desktop.
Rust code shared from the playground
use std::collections::BTreeMap;
// Why we might want multiple lifetimes...
// We want this structure to be trivially copyable as we pass it
// around and modify the position.
#[derive(Copy, Clone)]
struct Cache<'d, 's: 'd> {
data: &'d BTreeMap<usize, &'s str>,
position: usize,
}
impl<'d, 's> Cache<'d, 's> {
fn new(map: &'d BTreeMap<usize, &'s str>) -> Cache<'d, 's> {
Cache { data: map, position: 0 }
}
fn get(&self) -> &'s str {
&self.data[&self.position]
}
fn descend(&self) -> Cache<'d, 's> {
Cache {
position: self.position + 1,
..*self
}
}
}
fn foo<'d, 's>(cache: Cache<'d, 's>) -> &'s str {
// This could be much more complicated in real code, as we did things.
if cache.position < 1 {
foo(cache.descend())
} else {
cache.get()
}
}
fn main() { // LT0 LT1
let many_strings = ["foo", "bar"]; // 0 |
let the_string = { // 1 |
let mut map = BTreeMap::new(); // 2 | |
map.insert(0, many_strings[0]); // 3 | |
map.insert(1, many_strings[1]); // 4 | |
let cache = Cache::new(&map); // 5 | |
foo(cache) // 6 | |
}; // 7 |
println!("{}", the_string); // 8 |
}
// Concrete lifetime 0 is the lifetime of the strings, concrete
// lifetime 1 is the lifetime of the `BTreeMap`. If `Cache` had only
// one lifetime, the compiler would be forced to pick the intersection
// of the two concrete lifetimes when we created the `Cache`. That
// would mean that the returned string could only be guaranteed to
// exist until the end of the inner block, which is not what we want.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment