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?