Apa perbedaan antara `| _ | async move {} `dan` async move | _ | {} `

10

Mari kita perhatikan contoh-contoh berikut:

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"

Saya bertanya tentang ekspresi |x| async move {}bukan async move |x| {}. Yang terakhir lebih jelas, tetapi mengalami kesalahan kompilasi:

error[E0658]: async closures are unstable

Lalu aku bertanya-tanya, apa perbedaan antara async move || {}dan || async move {}. Keduanya sepertinya merupakan penutupan untuk menggunakan movekata kunci.

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

Jawaban:

7

Salah satunya adalah blok async (penutupan dengan blok async sebagai tubuhnya tepatnya), sedangkan yang lainnya adalah penutupan async. Per async / tunggu RFC :

async || penutupan

Selain fungsi, async juga dapat diterapkan pada penutupan. Seperti fungsi async, penutupan async memiliki tipe return impl Future<Output = T>, bukan T.

Di samping itu:

async blok

Anda dapat membuat masa depan secara langsung sebagai ekspresi menggunakan asyncblok. Formulir ini hampir setara dengan asyncpenutupan yang dilakukan langsung :

 async { /* body */ }

 // is equivalent to

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

kecuali bahwa aliran kontrol membangun suka return, breakdan continuetidak diizinkan di dalam tubuh.

Kata movekunci di sini adalah untuk menunjukkan bahwa penutupan dan blok async adalah untuk menangkap kepemilikan variabel yang mereka tutup.

Dan ternyata, penutupan async masih dianggap tidak stabil. Ini memiliki masalah pelacakan ini .

edwardw
sumber
Jadi tidak ada perbedaan dalam impornya sekarang, bukan?
dronte7
@ dronte7 tidak, terlepas dari kenyataan orang tidak stabil.
edwardw
mereka berdua segera berubah menjadi Masa Depan dengan atau tanpa memperoleh beberapa variabel surround. kecuali karena penutupan async yang tidak stabil sama dengan blok async dengan perolehan variabel eksternal, bukan?
dronte7
@ dronte7 mereka berdua mengembalikan Masa Depan saat dipanggil. Sejauh menangkap variabel, mereka juga sama. Itu artinya kependekan, async atau tidak.
edwardw
2
Saya pikir menangkap variabel sangat berbeda dalam kedua kasus. async move || ...akan memindahkan variabel dari blok penutup ke penutupan, sementara || async move {...}akan memindahkan variabel dari penutupan ke blok async. jika Anda ingin memindahkannya dari blok penutup ke blok async, saya rasa Anda perlu menggunakannya move || async move {...}untuk saat ini.
Sven Marnach