enum List<'a> {
Cons(isize, &'a List<'a>),
Nil,
}
fn main() {
use List::*;
use slotmap::SlotMap;
let mut table = SlotMap::new();
let nil = table.insert(Nil);
table.insert(Cons(1, table[nil]));
}
SlotMap<K: Key, V>‘s insert is
pub fn insert(&mut self, value: V) -> K
and its impl<K: Key, V> Index<K> is
fn index(&self, key: K) -> &V
So surely since I insert List into table, table[key] should return &List right?
Why am I getting this error:
error[E0308]: mismatched types
--> src/main.rs:11:26
|
11 | table.insert(Cons(1, table[nil]));
| ---- ^^^^^^^^^^
| | |
| | expected `&List<'_>`, found enum `List`
| | help: consider borrowing here: `&table[nil]`
| arguments to this enum variant are incorrect
|
How should I actually be using SlotMap to get many (immutable) references to SlotMap-owned objects?
>Solution :
Yes, index() returns a &V, but the operator [] works such that a[b] is equivalent to *a.index(b).
Which is handy, because when you write for example an array:
let mut a = [1,2,3];
a[0] = 0;
you don’t want to write *a[0] = 0;! And consider arrays of arrays… *(*m[0])[1] = 0;, that wouldn’t be pretty.
So if you want the reference to the value just reborrow (that is what the compiler suggests):
table.insert(Cons(1, &table[nil]));
Or alternatively call index manually:
table.insert(Cons(1, table.index(nil)));
But that begs the question, if you are adding all your lists and partial lists to the slotmap, why not:
enum List {
Cons(isize, Key),
Nil,
}
And get rid of lifetime issues forever?