take in core::mem - Rust (original) (raw)

Function take

1.40.0 (const: unstable) · Source

pub fn take<T: Default>(dest: &mut T) -> T

Expand description

Replaces dest with the default value of T, returning the previous dest value.

§Examples

A simple example:

use std::mem;

let mut v: Vec<i32> = vec![1, 2];

let old_v = mem::take(&mut v);
assert_eq!(vec![1, 2], old_v);
assert!(v.is_empty());

take allows taking ownership of a struct field by replacing it with an “empty” value. Without take you can run into issues like these:

struct Buffer<T> { buf: Vec<T> }

impl<T> Buffer<T> {
    fn get_and_reset(&mut self) -> Vec<T> {
        // error: cannot move out of dereference of `&mut`-pointer
        let buf = self.buf;
        self.buf = Vec::new();
        buf
    }
}

Note that T does not necessarily implement Clone, so it can’t even clone and resetself.buf. But take can be used to disassociate the original value of self.buf fromself, allowing it to be returned:

use std::mem;

impl<T> Buffer<T> {
    fn get_and_reset(&mut self) -> Vec<T> {
        mem::take(&mut self.buf)
    }
}

let mut buffer = Buffer { buf: vec![0, 1] };
assert_eq!(buffer.buf.len(), 2);

assert_eq!(buffer.get_and_reset(), vec![0, 1]);
assert_eq!(buffer.buf.len(), 0);