L'asincronia in Rust è implementata tramite Future — un oggetto che rappresenta un lavoro il cui risultato sarà ottenuto in futuro. Le funzioni dichiarate con async fn restituiscono una struttura generica anonima che implementa il trait Future. Per eseguire codice asincrono, è necessario un runtime (ad esempio, Tokio o async-std), poiché la libreria standard non include un event loop integrato.
Le principali caratteristiche di Rust:
Esempio:
use tokio::time::sleep; use std::time::Duration; async fn foo() { println!("Hello"); sleep(Duration::from_secs(1)).await; println!("World!"); } #[tokio::main] async fn main() { foo().await; }
Può una funzione asincrona in Rust essere eseguita immediatamente al momento della chiamata? Perché?
Risposta:
No. La chiamata a async fn restituisce non un risultato, ma un oggetto di tipo Future (macchina a stati). Per una reale esecuzione è necessario chiamare .await o passare il Future al runtime. La chiamata stessa crea solo una descrizione del compito, ma non lo esegue.
Esempio:
async fn answer() -> u32 { 42 } let fut = answer(); // qui non c'è esecuzione, solo creazione di future let result = fut.await; // l'esecuzione inizia qui
Storia
.await. Di conseguenza, i thread principali venivano eseguiti in modo sincrono, portando a un calo delle prestazioni e a un aumento dei tempi di risposta di 3 volte.Storia
Storia
Uno dei membri del team ha dimenticato le limitazioni Send/Sync sui tipi utilizzati all'interno di Future. Nel tentativo di condividere future tra i thread, l'applicazione è crashata con un errore di compilazione che richiedeva l'implementazione di Send per una determinata struttura, il che ha richiesto una revisione dell'architettura di conservazione dello stato.