Size: a a a

2020 October 22

DN

Denis Nevmerzhitskii in Rust Async
Подскажите, зачем здесь https://github.com/mitsuhiko/redis-rs/blob/f60933a467013de40bdf4a40288b551e09857160/src/commands.rs#L184 идёт оборачивание в Box::pin(async move { ... }), а не просто ($body).query_async(self)?
источник

ph

pl 🦑 hk in Rust Async
$(body).query_async -> impl Future
Box::pin(...) -> Pin<Box<dyn Future>>>
источник

DN

Denis Nevmerzhitskii in Rust Async
pl 🦑 hk
$(body).query_async -> impl Future
Box::pin(...) -> Pin<Box<dyn Future>>>
Это понятно, но зачем нужно pin'ить? В обычных примерах (низкоуровневый вызов) идёт простой вызов some_cmd.query_async(con).await. Но в случае "высокоуровневой" команды, тот же вызов query_async оборачивается в Box::pin.
источник

MB

Mikail Bagishov in Rust Async
Потому что трейт объявлен так, что требует возвращать BoxFuture-ы
источник

MB

Mikail Bagishov in Rust Async
В стейбл раста слелать лучше пока что не получится
источник

DN

Denis Nevmerzhitskii in Rust Async
Mikail Bagishov
Потому что трейт объявлен так, что требует возвращать BoxFuture-ы
то есть, если бы это была обычная функция (не в trait'е), то её можно было бы сделать async и просто возвращать результат query_async?
источник

MB

Mikail Bagishov in Rust Async
Да.
источник

MB

Mikail Bagishov in Rust Async
А в трейте это должно было выглядеть вот так:
trait ... {
   type Fut: std::future::Future<Output=...>;
   fn query(&self, ...) -> Self::Fut);
}
источник

MB

Mikail Bagishov in Rust Async
Но тогда без найтли фич не удастся реализовать этот трейт для асинхронной функции, потому что async fn возвращает некоторый анонимный тип, и указать его имя в type Fut = ... невозможно
источник

в🧇

вафель 🧇 in Rust Async
Mikail Bagishov
А в трейте это должно было выглядеть вот так:
trait ... {
   type Fut: std::future::Future<Output=...>;
   fn query(&self, ...) -> Self::Fut);
}
... но такой интерфейс не позволяет заимствовать self из-за отсутствия GAT
источник

в🧇

вафель 🧇 in Rust Async
Mikail Bagishov
Но тогда без найтли фич не удастся реализовать этот трейт для асинхронной функции, потому что async fn возвращает некоторый анонимный тип, и указать его имя в type Fut = ... невозможно
На стейбле можно точно так-же указать Fut = Pin<Box<...>>
источник

MB

Mikail Bagishov in Rust Async
вафель 🧇
На стейбле можно точно так-же указать Fut = Pin<Box<...>>
Ну да, но боксинг при этом никуда не делся
источник

MB

Mikail Bagishov in Rust Async
TL&DR: продолжаем ждать chalk.
источник

DN

Denis Nevmerzhitskii in Rust Async
ага, теперь понятно. Не до конца понятно, почему async не может быть в trait, но не уверен, что на данном этапе смогу понять) спасибо
источник

MB

Mikail Bagishov in Rust Async
Проблема не в самом асинке
источник

AV

A V in Rust Async
Пользуйтесь async_trait и всё
источник

MB

Mikail Bagishov in Rust Async
async fn(...) -> String
Это сахар для
fn(...) -> impl Future<Output = String>
источник

AV

A V in Rust Async
Потери от боксирования микроскопические и утонут в общей массе I/O
источник

в🧇

вафель 🧇 in Rust Async
Mikail Bagishov
Ну да, но боксинг при этом никуда не делся
Можно боксинг сделать feature-dependant X)
источник

в🧇

вафель 🧇 in Rust Async
A V
Пользуйтесь async_trait и всё
async_trait делает не естественные сигнатуры, лучше руками боксить
источник