Rust
8.14K subscribers
413 photos
39 videos
3 files
962 links
Rust programming language

По всем вопросам- @haarrp

@ai_machinelearning_big_data - машинное обучение

@programming_books_it - бесплатные it книги

@pythonl - 🐍

@ArtificialIntelligencedl - AI

@datascienceiot - ml 📚

#VRHSZ
Download Telegram
👣 Rust Совет

MaybeUninit для ручной сборки структур без лишнего drop

Когда значение собирается по частям в unsafe-коде, FFI, парсере или аллокаторе, главная проблема не в самой инициализации. Главная проблема - что делать, если ошибка произошла посередине.

Например, одно поле структуры уже создано, а второе еще нет. В этот момент нельзя дропать всю структуру целиком: для Rust она еще не является полностью готовым объектом.

Правильный подход - явно помнить, какие поля уже инициализированы, и очищать только их. Для этого используют MaybeUninit, ptr::write, drop_in_place и, когда значение уже полностью готово, assume_init_drop.

MaybeUninit нужен не “чтобы обмануть Rust”, а чтобы аккуратно управлять жизненным циклом там, где компилятор уже не может сделать это за тебя.

Для таких случаев есть MaybeUninit:


use std::mem::MaybeUninit;

struct Buffer {
data: Vec<u8>,
meta: String,
}

let mut value = MaybeUninit::<Buffer>::uninit();

unsafe {
let ptr = value.as_mut_ptr();

std::ptr::addr_of_mut!((*ptr).data).write(vec![1, 2, 3]);

// Если дальше случилась ошибка,
// дропаем только уже инициализированное поле
std::ptr::addr_of_mut!((*ptr).data).drop_in_place();

// А всю Buffer не трогаем:
// meta еще не была создана
}


Более удобный вариант для полностью инициализированного MaybeUninit<T>:


let mut value = MaybeUninit::new(String::from("hello"));

unsafe {
value.assume_init_drop();
}


MaybeUninit<T> используют не просто для создания значения “без инициализации”. Он нужен, когда ты сам управляешь моментом, в который память становится настоящим T, и сам отвечаешь за корректный drop.

Если структура собирается по частям, компилятор уже не всегда может понять, какие поля реально созданы. Поэтому unsafe-логику лучше держать внутри маленькой функции или типа, а наружу отдавать обычный safe API. Так риск ошибок остается локальным и проверяемым.

#rust #rustlang #programming #unsafeRust
Please open Telegram to view this post
VIEW IN TELEGRAM
9🔥4🥰3🥴2👍1🤗1