Vec - Removing an element at an index without removing elmenet

Hello,

I am trying to implement a circular buffer using Vec. Vec::insert() transfers ownership to the Vec. I am trying to find a way to be able to remove/extract the element from the Vec without "deleting" the "index" where the element is present.

I am running into the error "cannot move out of index of Vec<>". I thought of using an Option<>, but ran into same issue.

Following is code snippet of the API

pub struct CircularBuffer<T> {
    // ...
}

impl<T> CircularBuffer<T> {
    pub fn new(capacity: usize) -> Self { todo!() }
    pub fn write(&mut self, element: T) -> Result<(), Error> { todo!() }
    pub fn read(&mut self) -> Result<T, Error> { todo!() }
}

Would appreciate any pointers.
(In C++ I would use an array of ptrs, setting element to null when value at an index is empty.).

Regards,
Ahmed.

The Rust equivalent would be an Option<Box<T>>.

I suggest giving that another try.

The issue is that the element in the Vec must be something. i.e. the memory in the vec must be valid instance of T.

Instead of assigning from the element in the vec, try using mem::take

That gives you ownership of the value, and replaces the object at the index in the Vec with None

you need Option::take().

3 Likes

In case you are not aware, there is already a data structure provided for a circular buffer: VecDeque. Vec always has a contiguous range of initialized elements, but VecDeque is able to have the uninitialized part (spare capacity) be somewhere in the middle of its allocation, which is the key difference that makes VecDeque more powerful than Vec.

If you want to build a circular buffer out of Vec for practice, then you need Option as already discussed, but if you just want to use a circular buffer, you should use VecDeque.

4 Likes

Thank you. This is exactly the functionality/method I was looking for. Using take() and insert() allowed for a clean solution.

1 Like