Чим відрізняється `| _ | async move {} `та` async move | _ | {} `


10

Розглянемо наступні приклади:

main.rs

use futures::executor::block_on;
use futures::future::{FutureExt, TryFutureExt};


async fn fut1() -> Result<String, u32> {
  Ok("ok".to_string())
}

fn main() {
    println!("Hello, world!");
    match block_on(fut1().and_then(|x| async move { Ok(format!("{} is \"ok\"", x)) })) {
      Ok(s) => println!("{}", s),
      Err(u) => println!("{}", u)
    };
}

Cargo.toml

[dependencies]
futures = "^0.3"

Я запитую про вираз |x| async move {}замість async move |x| {}. Останнє є більш очевидним, але воно стикається з помилкою компіляції:

error[E0658]: async closures are unstable

Тоді мені цікаво, в чому різниця між async move || {}і || async move {}. Здається, вони обидва є закриттям для використання moveключового слова.

$ rustc --version
rustc 1.39.0 (4560ea788 2019-11-04)

Відповіді:


6

Один - це блок асинхронізації (закриття з блоком асинхронізації як точного тіла), а другий - закриття асинхронізації. За асинхронізацію / очікування RFC :

async || закриття

Крім функцій, асинхронізація може застосовуватися і до закриттів. Як і функція асинхронізації, закриття асинхронізації має тип повернення impl Future<Output = T>, а не T.

З іншої сторони:

async блоки

Ви можете створити майбутнє безпосередньо як вираз за допомогою asyncблоку. Ця форма майже еквівалентна негайно закритому asyncзакриттю:

 async { /* body */ }

 // is equivalent to

 (async || { /* body */ })()

крім того, що конструкції управління потоком , як return, breakі continueне допускається в межах тіла.

moveКлючове слово тут , щоб позначити , що замикання асинхронного і блок є власністю захоплення змінних вони близькі більш.

І, мабуть, закриття асинхронізації все ще вважається нестабільним. У ньому є ця проблема відстеження .


Отже, зараз немає різниці в його імпорті, чи не так?
dronte7

@ dronte7 nope, крім того, що одна нестабільна.
edwardw

вони обидва одразу перетворюються на майбутнє з ot без придбання деяких оточуючих змінних. окрім того, що нестабільне закриття асинхронізації те саме, що блок асинхронізації з придбанням зовнішніх змінних, чи не так?
dronte7

@ dronte7 вони обидва повертають Майбутнє, коли їх називають. Щодо захоплення змінних, вони також однакові. Ось що означає закриття, асинхронізація чи ні.
edwardw

2
Я думаю, що в обох випадках фіксація змінних сильно відрізняється. async move || ...перемістить змінні з блоку, що додається, до закриття, тоді як || async move {...}змінює змінні з закриття в блок асинхронізації. якщо ви хочете перенести їх із блоку, що додається, до блоку асинхронізації, я вважаю, що ви повинні використовувати його move || async move {...}наразі.
Свен Марнах
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.