rustvectordeque

How to transfer ownership of Vec into a VecDeque?


In the following code, I want to transfer the staged_bytes vector into the buffer. Specifically, I want 'buffer' to take ownership of staged_bytes so that I can reuse the staged_bytes field for a brand new vector of u8.

I show a solution to my problem in the code. Unfortunately according to rust documentation, it implies a copy of the vector elements. Since that vector can be big, I don't want the copy, hence my desire for an ownership transfer.

I think I can't do it the way I want because the ownership is at the same time in staged_bytes and buffer during the transfer().

So what are the solutions ? I thought of shared pointers (Rc, etc.) but it seems overkill since it's not actually shared (maybe the optimizer figures it out ?)...

use std::collections::VecDeque;

struct M {
    buffer : VecDeque<Vec<u8>>,
    staged_bytes: Vec<u8>
}

impl M {
    fn transfer(&mut self) {

        // This is what I want to do (the idea)
        // (it doesn't compile, E0507)
        // self.buffer.push_front(self.staged_bytes);

        // This is what I don't want to do
        // (it compiles)
        self.buffer.push_front(self.staged_bytes.clone());

        // After the transfer, I can start with a new vec.
        self.staged_bytes = Vec::new();
    }
}

fn main() {
    let mut s = M {
        buffer : VecDeque::new(),
        staged_bytes: Vec::new()
    };

    s.staged_bytes.push(112);
    s.transfer();
}

Solution

  • You want to use std::mem::take() here, which returns the value moved from a mutable reference and replaces it with the default value of the type:

    self.buffer.push_front(std::mem::take(&mut self.staged_bytes));
    

    Since the default value of a Vec is an empty vector, you can remove the following assignment (self.staged_bytes = Vec::new();) as it is redundant.