std::mem::takeТипичная ситуация: у вас есть
&mut self, и вы хотите забрать поле (например, String или Vec), что-то с ним сделать, и, возможно, вернуть обратно или сохранить измененную версию.Компилятор бьет по рукам: нельзя просто так переместить (move) значение из-за мутабельной ссылки. Новички часто делают
.clone(), чтобы успокоить borrow checker. Но это лишняя аллокация!Решение:
std::mem::take.Оно забирает значение из ссылки, оставляя на его месте
Default::default().
struct Buffer {
data: Vec<u8>,
}
impl Buffer {
fn process(&mut self) {
// Мы "выкрадываем" вектор.
// В self.data теперь пустой Vec (без аллокаций).
let raw_data = std::mem::take(&mut self.data);
// Тяжелая обработка в другом потоке/функции,
// требующая владения (ownership)
let processed = heavy_transform(raw_data);
// Возвращаем результат
self.data = processed;
}
}
Это работает для всего, что реализует
Default (Option, String, Vec). Для типов без Default есть std::mem::replace.Это zero-cost, семантически верно и намного быстрее клонирования.
#rust #std #optimization #tips
📲 Мы в MAX
👉 @rust_lib