Is there a way to get reference to a value contained in enum without `match/if let/let else` checking?

⚓ Rust    📅 2025-06-24    👤 surdeus    👁️ 7      

surdeus

Warning

This post was published 49 days ago. The information described in this article may have changed.

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")   
    }
  }
}

2 posts - 2 participants

Read full topic

🏷️ rust_feed