¿Cuál es la diferencia entre `| _ | movimiento asíncrono {} `y` movimiento asíncrono | _ | {} `


10

Consideremos los siguientes ejemplos:

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"

Estoy preguntando por la expresión en |x| async move {}lugar de async move |x| {}. Esto último es más obvio, pero se encuentra con el error de compilación:

error[E0658]: async closures are unstable

Entonces me pregunto cuál es la diferencia entre async move || {}y || async move {}. Ambos parecen ser cierres por usar la movepalabra clave.

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

Respuestas:


7

Uno es el bloque asíncrono (un cierre con bloque asíncrono como su cuerpo para ser precisos), mientras que el otro es el cierre asíncrono. Por asíncrono / espera RFC :

async || cierres

Además de las funciones, async también se puede aplicar a los cierres. Al igual que una función asíncrona, un cierre asíncrono tiene un tipo de retorno de impl Future<Output = T>, en lugar de T.

Por otra parte:

async bloques

Puede crear un futuro directamente como una expresión usando un asyncbloque. Este formulario es casi equivalente a un asynccierre invocado de inmediato :

 async { /* body */ }

 // is equivalent to

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

excepto que las construcciones de flujo de control como return, breaky continueno están permitidos dentro del cuerpo.

La movepalabra clave aquí es denotar que el cierre y el bloqueo asíncronos son para capturar la propiedad de las variables que cierran.

Y aparentemente, el cierre asíncrono todavía se considera inestable. Tiene este problema de seguimiento .


Entonces no hay diferencia en su importación en este momento, ¿no?
dronte7

@ dronte7 no, aparte del hecho de que uno es inestable.
edwardw

Ambos se convierten inmediatamente en un futuro sin adquirir algunas variables envolventes. excepto por ser inestable, el cierre asíncrono es lo mismo que el bloqueo asíncrono con la adquisición de variables externas, ¿no es así?
dronte7

@ dronte7 ambos devuelven un futuro cuando se les llama. En cuanto a la captura de variables, también son las mismas. Eso es lo que significa el cierre, asíncrono o no.
edwardw

2
Creo que capturar variables es bastante diferente en ambos casos. async move || ...moverá las variables del bloque de cierre al cierre, mientras || async move {...}que moverá las variables del cierre al bloque asíncrono. si desea moverlos desde el bloque que lo encierra al bloque asíncrono, creo que debe usarlo move || async move {...}por ahora.
Sven Marnach
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.