Qual è la differenza tra `| _ | mossa asincrona {} `e` mossa asincrona | _ | {} `


10

Consideriamo i seguenti esempi:

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"

Sto chiedendo dell'espressione |x| async move {}invece di async move |x| {}. Quest'ultimo è più ovvio, ma si imbatte nell'errore di compilazione:

error[E0658]: async closures are unstable

Quindi mi chiedo, qual è la differenza tra async move || {}e || async move {}. Entrambi sembrano essere chiusure per l'utilizzo della moveparola chiave.

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

Risposte:


7

Uno è il blocco asincrono (una chiusura con blocco asincrono come corpo per essere precisi), mentre l'altro è la chiusura asincrona. Per asincrono / attendi RFC :

async || chiusure

Oltre alle funzioni, asincrono può essere applicato anche alle chiusure. Come una funzione asincrona, una chiusura asincrona ha un tipo di ritorno impl Future<Output = T>piuttosto che T.

D'altro canto:

async blocchi

Puoi creare un futuro direttamente come espressione usando un asyncblocco. Questo modulo è quasi equivalente a una asyncchiusura immediatamente invocata :

 async { /* body */ }

 // is equivalent to

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

eccetto che costrutti di controllo del flusso come return, breake continuenon sono ammessi all'interno del corpo.

La moveparola chiave qui sta per indicare che la chiusura asincrona e il blocco devono acquisire la proprietà delle variabili che chiudono.

E a quanto pare, la chiusura asincrona è ancora considerata instabile. Ha questo problema di tracciamento .


Quindi non c'è differenza nella sua importazione in questo momento, vero?
dronte7,

@ dronte7 no, a parte il fatto che è instabile.
Edwardw,

entrambi si trasformano immediatamente in un Futuro senza ot senza acquisire alcune variabili surround. tranne che per la chiusura asincrona instabile è uguale al blocco asincrono con l'acquisizione di variabili esterne, non è vero?
dronte7,

@ dronte7 entrambi restituiscono un futuro quando vengono chiamati. Per quanto riguarda l'acquisizione di variabili, sono uguali. Ecco cosa significa chiusura, asincrona o no.
Edwardw,

2
Penso che catturare le variabili sia abbastanza diverso in entrambi i casi. async move || ...sposterà le variabili dal blocco racchiuso nella chiusura, mentre || async move {...}sposterà le variabili dalla chiusura nel blocco asincrono. se vuoi spostarli dal blocco che lo racchiude nel blocco asincrono, credo che move || async move {...}per ora devi usarlo .
Sven Marnach,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.