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
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