Consider the following code. In fn insert
I set the value of the enum
based on some conditions and then return a &mut
to the contained value. The only way I could do this was using match
(or perhaps if let / let else
. However, I know that I have just set the enum
in Part 1 so having a check again with match/if let/let else
in Part 2 seems unnecessary. Is there a way to get reference to a value contained in enum without match/if let/let else
checking? (also unsafe
is ok).
pub enum Slot<T> {
Empty,
WasOccupied,
IsOccupiedBy(T),
}
struct Entry<V> {
... // other struct members
value: V,
}
...
struct MyStruct<V> {
_data: Vec<Slot<Entry<V>>>,
...
}
...
impl<V> MyStruct<V> {
//update existing value or insert new and return old value and mut ref to to new value
fn insert(&mut self, v: V) -> Result<(Option<V>, &mut V), OutOfCapacityError>
let mut old_val: Option<V> = None;
// Part 1: Set a value
match self._data[i] {
Slot::IsOccupiedBy(ref mut entry) => {
old_val = Some(mem::replace(&mut entry.value, value));
}
Slot::Empty | Slot::WasOccupied => {
self._data[i] = Slot::IsOccupiedBy(Entry {
... // other struct members
value,
});
}
}
//.... some more code that doesn't update/mutate self._data
// Part 2: return the &mut to the contained value
match self._data[i] { // At this point I already know self._data[i] has an Entry containing value
Slot::IsOccupiedBy(ref mut entry) => {
return Result::Ok((old_val, &mut entry.value))
}
_ => panic!("Unreachable!! Something went horribly wrong if I hit this line")
}
}
}