Макрос pin
Источник: Документация futures-lite::pin
#![allow(unused)] fn main() { macro_rules! pin { ($($x:ident),* $(,)?) => { ... }; } }
Фиксирует переменную типа T в стеке и перепривязывает её как Pin<&mut T>.
Примеры
#![allow(unused)] fn main() { use futures_lite::{future, pin}; use std::fmt::Debug; use std::future::Future; use std::pin::Pin; use std::time::Instant; // Инспектирует каждый вызов `Future::poll()`. async fn inspect<T: Debug>(f: impl Future<Output = T>) -> T { pin!(f); future::poll_fn(|cx| dbg!(f.as_mut().poll(cx))).await } let f = async { 1 + 2 }; inspect(f).await; }
Описание
Макрос pin! используется для безопасного закрепления (pinning) переменных в стеке. Это особенно полезно при работе с асинхронным кодом, где необходимо гарантировать, что данные не будут перемещены в памяти после того, как на них созданы ссылки в асинхронных фьючерсах.
Как работает
- Принимает один или несколько идентификаторов переменных
- Для каждой переменной создает закрепленную ссылку
Pin<&mut T> - Перепривязывает исходную переменную к закрепленной версии
Использование
#![allow(unused)] fn main() { use futures_lite::pin; let mut value = SomeFuture::new(); pin!(value); // Теперь `value` имеет тип `Pin<&mut SomeFuture>` // Можно использовать закрепленную переменную let pinned = value.as_mut(); }
Макрос обеспечивает безопасное закрепление, которое необходимо для вызова методов poll на фьючерсах и других типах, требующих гарантий неперемещаемости.