Rust
2.25K subscribers
173 photos
109 videos
2 files
260 links
Полезный контент по программированию на Rust
Download Telegram
👻 Сила пустоты: Zero-Sized Types (ZST)

Мы часто говорим про "zero-cost abstractions", но редко задумываемся, как это выглядит в памяти. ZST - это типы, которые занимают 0 байт. Компилятор знает о них, но в рантайме они исчезают.

Зачем это нужно, кроме экономии памяти? Для управления состоянием на уровне типов.

Представьте, что у вас есть стейт-машина. Вместо того чтобы хранить enum State и делать проверки в рантайме:


struct Socket<State> {
inner: FileDesc,
_marker: PhantomData<State>, // 0 байт
}

// ZST-маркеры
struct Connected;
struct Disconnected;

impl Socket<Disconnected> {
fn connect(self) -> Socket<Connected> {
// Логика подключения...
// Трансформация типа без оверхеда в памяти
unsafe { std::mem::transmute(self) }
}
}

impl Socket<Connected> {
fn send(&self, data: &[u8]) { ... }
}



В чем профит?

1. Вы физически не можете вызвать метод send у Disconnected сокета. Код просто не скомпилируется.
2. В скомпилированном бинарнике нет никаких флагов состояния, if state == connected и прочего мусора. Метод просто вызывается.

Используйте систему типов, чтобы делать некорректные состояния невыразимыми (Make invalid states unrepresentable).

#rust #advanced #architecture #zst

👉 @rust_lib
❤16🔥8
👻 Сила пустоты: Zero-Sized Types (ZST)

Мы часто говорим про "zero-cost abstractions", но редко задумываемся, как это выглядит в памяти. ZST - это типы, которые занимают 0 байт. Компилятор знает о них, но в рантайме они исчезают.

Зачем это нужно, кроме экономии памяти? Для управления состоянием на уровне типов.

Представьте, что у вас есть стейт-машина. Вместо того чтобы хранить enum State и делать проверки в рантайме:


struct Socket<State> {
inner: FileDesc,
_marker: PhantomData<State>, // 0 байт
}

// ZST-маркеры
struct Connected;
struct Disconnected;

impl Socket<Disconnected> {
fn connect(self) -> Socket<Connected> {
// Логика подключения...
// Трансформация типа без оверхеда в памяти
unsafe { std::mem::transmute(self) }
}
}

impl Socket<Connected> {
fn send(&self, data: &[u8]) { ... }
}



В чем профит?

1. Вы физически не можете вызвать метод send у Disconnected сокета. Код просто не скомпилируется.
2. В скомпилированном бинарнике нет никаких флагов состояния, if state == connected и прочего мусора. Метод просто вызывается.

Используйте систему типов, чтобы делать некорректные состояния невыразимыми (Make invalid states unrepresentable).

#rust #advanced #architecture #zst

📲 Мы в MAX

👉 @rust_lib
❤10👍1